diff --git a/RobotApp.Client/ClientRenderMode.cs b/RobotApp.Client/ClientRenderMode.cs
new file mode 100644
index 0000000..def79c3
--- /dev/null
+++ b/RobotApp.Client/ClientRenderMode.cs
@@ -0,0 +1,8 @@
+using Microsoft.AspNetCore.Components.Web;
+
+namespace RobotApp.Client;
+
+public class ClientRenderMode
+{
+ public static InteractiveWebAssemblyRenderMode InteractiveWebAssemblyNoPrerender { get; } = new(prerender: false);
+}
diff --git a/RobotApp.Client/Layout/MainLayout.razor b/RobotApp.Client/Layout/MainLayout.razor
deleted file mode 100644
index 81e3cf1..0000000
--- a/RobotApp.Client/Layout/MainLayout.razor
+++ /dev/null
@@ -1,20 +0,0 @@
-@inherits LayoutComponentBase
-@using MudBlazor
-
-
-
-
-
-
-
-
-
- @Body
-
-
-
-
-
-
-
-
diff --git a/RobotApp.Client/Layout/MainLayout.razor.css b/RobotApp.Client/Layout/MainLayout.razor.css
deleted file mode 100644
index da43ded..0000000
--- a/RobotApp.Client/Layout/MainLayout.razor.css
+++ /dev/null
@@ -1,17 +0,0 @@
-
-.app-shell {
- display: flex;
- min-height: 100vh;
- min-width: 100vw;
- width: 100vw;
- height: 100vh;
- overflow: hidden;
- flex-direction: row;
-}
-
-.page {
- flex: 1 1 auto;
- min-width: 0;
- display: flex;
- overflow: hidden;
-}
diff --git a/RobotApp.Client/Layout/NavMenu.razor b/RobotApp.Client/Layout/NavMenu.razor
deleted file mode 100644
index da332e9..0000000
--- a/RobotApp.Client/Layout/NavMenu.razor
+++ /dev/null
@@ -1,78 +0,0 @@
-@using Microsoft.AspNetCore.Components.Routing
-
-
-
-
-
-@code {
- public class NavModel
- {
- public string Icon { get; set; } = "";
- public string Path { get; set; } = "";
- public string Label { get; set; } = "";
- public NavLinkMatch Match { get; set; }
- }
-
- public NavModel[] Navs = [
- new(){Icon = "mdi-view-dashboard", Path="/", Label = "Dashboard", Match = NavLinkMatch.All},
- new(){Icon = "mdi-map-legend", Path="/Maps-manager", Label = "Mapping", Match = NavLinkMatch.All},
- ];
-
- private bool collapseNavMenu = true;
-
- private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
-
- private void ToggleNavMenu()
- {
- collapseNavMenu = !collapseNavMenu;
- }
-}
diff --git a/RobotApp.Client/MainLayout.razor b/RobotApp.Client/MainLayout.razor
new file mode 100644
index 0000000..373fcfd
--- /dev/null
+++ b/RobotApp.Client/MainLayout.razor
@@ -0,0 +1,85 @@
+@inherits LayoutComponentBase
+
+
+
+
+
+
+
+ @Body
+
+
+
+@code{
+ public class NavModel
+ {
+ public string Icon { get; set; } = "";
+ public string Path { get; set; } = "";
+ public string Label { get; set; } = "";
+ public NavLinkMatch Match { get; set; }
+ }
+
+ public NavModel[] Navs = [
+ new(){Icon = "mdi-view-dashboard", Path="/", Label = "Dashboard", Match = NavLinkMatch.All},
+ new(){Icon = "mdi-map-legend", Path="/maps-manager", Label = "Mapping", Match = NavLinkMatch.All},
+ ];
+
+ private bool collapseNavMenu = true;
+
+ private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
+
+ private void ToggleNavMenu()
+ {
+ collapseNavMenu = !collapseNavMenu;
+ }
+}
+
diff --git a/RobotApp.Client/Layout/NavMenu.razor.css b/RobotApp.Client/MainLayout.razor.css
similarity index 90%
rename from RobotApp.Client/Layout/NavMenu.razor.css
rename to RobotApp.Client/MainLayout.razor.css
index f4221f4..b57ef21 100644
--- a/RobotApp.Client/Layout/NavMenu.razor.css
+++ b/RobotApp.Client/MainLayout.razor.css
@@ -1,3 +1,21 @@
+.app-shell {
+ display: flex;
+ min-height: 100vh;
+ min-width: 100vw;
+ width: 100vw;
+ height: 100vh;
+ overflow: hidden;
+ flex-direction: row;
+}
+
+.page {
+ flex: 1 1 auto;
+ min-width: 0;
+ display: flex;
+ overflow: hidden;
+}
+
+
.sidebar {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
diff --git a/RobotApp.Client/Pages/AssemblyLayout.razor b/RobotApp.Client/Pages/AssemblyLayout.razor
new file mode 100644
index 0000000..faec1f3
--- /dev/null
+++ b/RobotApp.Client/Pages/AssemblyLayout.razor
@@ -0,0 +1,12 @@
+@inherits LayoutComponentBase
+@layout RobotApp.Client.MainLayout
+
+
+
+
+
+
+@Body
\ No newline at end of file
diff --git a/RobotApp.Client/Pages/Auth.razor b/RobotApp.Client/Pages/Auth.razor
deleted file mode 100644
index b7bbe6e..0000000
--- a/RobotApp.Client/Pages/Auth.razor
+++ /dev/null
@@ -1,13 +0,0 @@
-@page "/auth"
-
-@using Microsoft.AspNetCore.Authorization
-
-@attribute [Authorize]
-
-Auth
-
-You are authenticated
-
-
- Hello @context.User.Identity?.Name!
-
diff --git a/RobotApp.Client/Pages/Components/Mapping/MapPreview.razor b/RobotApp.Client/Pages/Components/Mapping/MapPreview.razor
new file mode 100644
index 0000000..e66b320
--- /dev/null
+++ b/RobotApp.Client/Pages/Components/Mapping/MapPreview.razor
@@ -0,0 +1,40 @@
+@inject HttpClient Http
+
+
+
@MapName
+
+
+

+
+
+ DOWNLOAD
+
+
+
+
+@code {
+ private bool Disable = true;
+ private string imageSrc = "/images/Image-not-found.png";
+ private string MapName = "Map preview";
+ private Guid MapId = Guid.Empty;
+
+
+ public void SetMapPreview(MapDto? map)
+ {
+ if (map is null)
+ {
+ Disable = true;
+ MapName = "Map preview";
+ imageSrc = "/images/Image-not-found.png";
+ MapId = Guid.Empty;
+ }
+ else
+ {
+ imageSrc = $"api/Images/map/{map.Id}?t={DateTime.Now}";
+ MapName = map.Name;
+ MapId = map.Id;
+ Disable = false;
+ }
+ StateHasChanged();
+ }
+}
diff --git a/RobotApp.Client/Pages/Components/Mapping/MapPreview.razor.css b/RobotApp.Client/Pages/Components/Mapping/MapPreview.razor.css
new file mode 100644
index 0000000..ac1ded4
--- /dev/null
+++ b/RobotApp.Client/Pages/Components/Mapping/MapPreview.razor.css
@@ -0,0 +1,42 @@
+.map-item {
+ display: flex;
+ justify-content: center;
+ width: 100%;
+ height: fit-content;
+}
+
+ .map-item img {
+ justify-content: center;
+ width: 95%;
+ height: 400px;
+ object-fit: contain;
+ border-radius: 10px;
+ image-rendering: pixelated;
+ }
+
+.title {
+ display: flex;
+ height: 77px;
+ width: 100%;
+ justify-content: center;
+ align-content: center;
+ /*border-bottom: 0.5px solid gray;*/
+ font-size: 30px;
+ flex-wrap: wrap;
+ padding-bottom: .5rem;
+}
+
+.map-update-item {
+ display: flex;
+ justify-content: center;
+ width: 100%;
+ height: fit-content;
+}
+
+ .map-update-item img {
+ width: 100%;
+ height: 400px;
+ object-fit: contain;
+ border-radius: 10px;
+ image-rendering: pixelated;
+ }
diff --git a/RobotApp.Client/Pages/Components/Mapping/MapTable.razor b/RobotApp.Client/Pages/Components/Mapping/MapTable.razor
new file mode 100644
index 0000000..1a306cd
--- /dev/null
+++ b/RobotApp.Client/Pages/Components/Mapping/MapTable.razor
@@ -0,0 +1,165 @@
+@inject HttpClient Http
+
+
+
+
+
+
+ Maps
+
+
+ Nr
+ Name
+ Width (m)
+ Height (m)
+ Resolution (m/px)
+ OriginX
+ OriginY
+
+
+
+
+ @(Table?.CurrentPage * Table?.RowsPerPage + MapsShow.IndexOf(context) + 1)
+
+
+ @context.Name
+
+
+ @context.Width
+
+
+ @context.Height
+
+
+ @context.Resolution
+
+
+ @context.OriginX
+
+
+ @context.OriginY
+
+
+ Active
+ Delete
+
+
+
+
+
+
+
+
+
+
+@code {
+
+ private string txtSearch = "";
+ private bool IsLoading = false;
+
+ private List Maps = [];
+ private List MapsShow = [];
+
+ private int selectedRowNumber = -1;
+ private MapDto MapSelected = new();
+
+ private MudTable? Table;
+
+ private MapPreview? MapPreviewRef;
+
+ protected override async Task OnAfterRenderAsync(bool firstRender)
+ {
+ await base.OnAfterRenderAsync(firstRender);
+ if (!firstRender) return;
+
+ // await LoadMaps();
+ }
+
+ private async Task LoadMaps()
+ {
+ try
+ {
+ IsLoading = true;
+ Maps.Clear();
+ StateHasChanged();
+
+ var maps = await Http.GetFromJsonAsync>($"api/MapsManager?txtSearch={txtSearch}");
+ Maps.AddRange(maps ?? []);
+
+ Table?.ReloadServerData();
+ IsLoading = false;
+ StateHasChanged();
+ }
+ catch
+ {
+ return;
+ }
+ }
+
+ private void TextSearchChanged(string text)
+ {
+ txtSearch = text;
+ Table?.ReloadServerData();
+ }
+
+ private bool FilterFunc(MapDto map)
+ {
+ if (string.IsNullOrWhiteSpace(txtSearch))
+ return true;
+ if (map.Name is not null && map.Name.Contains(txtSearch, StringComparison.OrdinalIgnoreCase))
+ return true;
+ if ($"{map.Name}".Contains(txtSearch))
+ return true;
+ return false;
+ }
+
+ private Task> ReloadData(TableState state, CancellationToken _)
+ {
+ MapsShow.Clear();
+ var tasks = new List();
+ Maps.ForEach(map =>
+ {
+ if (FilterFunc(map)) tasks.Add(map);
+ });
+ MapsShow = tasks.Skip(state.Page * state.PageSize).Take(state.PageSize).ToList();
+ return Task.FromResult(new TableData() { TotalItems = tasks.Count, Items = MapsShow });
+ }
+
+ private void RowClickEvent(TableRowClickEventArgs tableRowClickEventArgs) { }
+
+ private string SelectedRowClassFunc(MapDto element, int rowNumber)
+ {
+ if (selectedRowNumber == rowNumber && Table?.SelectedItem != null && !Table.SelectedItem.Equals(element))
+ {
+ return string.Empty;
+ }
+ else if (selectedRowNumber == rowNumber && Table?.SelectedItem != null && Table.SelectedItem.Equals(element))
+ {
+ return "selected";
+ }
+ else if (Table?.SelectedItem != null && Table.SelectedItem.Equals(element))
+ {
+ selectedRowNumber = rowNumber;
+ MapSelected = element;
+ // MapPreviewRef?.SetMapPreview(MapSelected);
+ return "selected";
+ }
+ else
+ {
+ return string.Empty;
+ }
+ }
+}
diff --git a/RobotApp.Client/Pages/Components/Mapping/MapTable.razor.css b/RobotApp.Client/Pages/Components/Mapping/MapTable.razor.css
new file mode 100644
index 0000000..6deaf98
--- /dev/null
+++ b/RobotApp.Client/Pages/Components/Mapping/MapTable.razor.css
@@ -0,0 +1,5 @@
+.map-preview {
+ width: 20%;
+ height: 100%;
+ border-left: 1px solid silver;
+}
diff --git a/RobotApp.Client/Components/Mapping/MapView.razor b/RobotApp.Client/Pages/Components/Mapping/MapView.razor
similarity index 100%
rename from RobotApp.Client/Components/Mapping/MapView.razor
rename to RobotApp.Client/Pages/Components/Mapping/MapView.razor
diff --git a/RobotApp.Client/Pages/Counter.razor b/RobotApp.Client/Pages/Counter.razor
deleted file mode 100644
index ef23cb3..0000000
--- a/RobotApp.Client/Pages/Counter.razor
+++ /dev/null
@@ -1,18 +0,0 @@
-@page "/counter"
-
-Counter
-
-Counter
-
-Current count: @currentCount
-
-
-
-@code {
- private int currentCount = 0;
-
- private void IncrementCount()
- {
- currentCount++;
- }
-}
diff --git a/RobotApp.Client/Pages/MapsManager.razor b/RobotApp.Client/Pages/MapsManager.razor
index ebf6ea2..cff3a98 100644
--- a/RobotApp.Client/Pages/MapsManager.razor
+++ b/RobotApp.Client/Pages/MapsManager.razor
@@ -1,181 +1,20 @@
@page "/maps-manager"
-@using MudBlazor
-@using RobotApp.Common.Shares.Dtos
+
+@rendermode InteractiveWebAssemblyNoPrerender
@attribute [Authorize]
-@inject HttpClient Http
Map Manager
-
-
-
-
-
-
-
- NEW
-
-
-
-
-
- Nr
- Name
- Width (m)
- Height (m)
- Resolution (m/px)
- OriginX
- OriginY
-
-
-
-
- @(Table?.CurrentPage * Table?.RowsPerPage + MapsShow.IndexOf(context) + 1)
-
-
- @context.Name
-
-
- @context.Width
-
-
- @context.Height
-
-
- @context.Resolution
-
-
- @context.OriginX
-
-
- @context.OriginY
-
-
-
-
- Edit
- Delete
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
@code {
- private string txtSearch = "";
- private bool IsLoading = false;
-
- private List
Maps = [];
private List MapsShow = [];
-
- private int selectedRowNumber = -1;
- private MapDto MapSelected = new();
-
- private MudTable? Table; protected override async Task OnAfterRenderAsync(bool firstRender)
- {
- await base.OnAfterRenderAsync(firstRender);
- if (!firstRender) return;
-
- await LoadMaps();
- }
-
- private async Task LoadMaps()
- {
- try
- {
- IsLoading = true;
- Maps.Clear();
- StateHasChanged();
-
- var maps = await Http.GetFromJsonAsync>($"api/MapsManager?txtSearch={txtSearch}");
- Maps.AddRange(maps ?? []);
-
- Table?.ReloadServerData();
- IsLoading = false;
- StateHasChanged();
- }
- catch
- {
- return;
- }
- }
-
- private void TextSearchChanged(string text)
- {
- txtSearch = text;
- Table?.ReloadServerData();
- }
-
- private bool FilterFunc(MapDto map)
- {
- if (string.IsNullOrWhiteSpace(txtSearch))
- return true;
- if (map.Name is not null && map.Name.Contains(txtSearch, StringComparison.OrdinalIgnoreCase))
- return true;
- if ($"{map.Name}".Contains(txtSearch))
- return true;
- return false;
- }
-
- private Task> ReloadData(TableState state, CancellationToken _)
- {
- MapsShow.Clear();
- var tasks = new List();
- Maps.ForEach(map =>
- {
- if (FilterFunc(map)) tasks.Add(map);
- });
- MapsShow = tasks.Skip(state.Page * state.PageSize).Take(state.PageSize).ToList();
- return Task.FromResult(new TableData() { TotalItems = tasks.Count, Items = MapsShow });
- }
-
- private void RowClickEvent(TableRowClickEventArgs tableRowClickEventArgs) { }
-
- private string SelectedRowClassFunc(MapDto element, int rowNumber)
- {
- if (selectedRowNumber == rowNumber && Table?.SelectedItem != null && !Table.SelectedItem.Equals(element))
- {
- return string.Empty;
- }
- else if (selectedRowNumber == rowNumber && Table?.SelectedItem != null && Table.SelectedItem.Equals(element))
- {
- return "selected";
- }
- else if (Table?.SelectedItem != null && Table.SelectedItem.Equals(element))
- {
- selectedRowNumber = rowNumber;
- MapSelected = element;
- // NavigationMapPreviewRef.SetMapPreview(MapSelected);
- return "selected";
- }
- else
- {
- return string.Empty;
- }
- }
}
diff --git a/RobotApp.Client/Pages/Weather.razor b/RobotApp.Client/Pages/Weather.razor
deleted file mode 100644
index dd36b18..0000000
--- a/RobotApp.Client/Pages/Weather.razor
+++ /dev/null
@@ -1,63 +0,0 @@
-@page "/weather"
-
-Weather
-
-Weather
-
-This component demonstrates showing data.
-
-@if (forecasts == null)
-{
- Loading...
-}
-else
-{
-
-
-
- | Date |
- Temp. (C) |
- Temp. (F) |
- Summary |
-
-
-
- @foreach (var forecast in forecasts)
- {
-
- | @forecast.Date.ToShortDateString() |
- @forecast.TemperatureC |
- @forecast.TemperatureF |
- @forecast.Summary |
-
- }
-
-
-}
-
-@code {
- private WeatherForecast[]? forecasts;
-
- protected override async Task OnInitializedAsync()
- {
- // Simulate asynchronous loading to demonstrate a loading indicator
- await Task.Delay(500);
-
- var startDate = DateOnly.FromDateTime(DateTime.Now);
- var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };
- forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast
- {
- Date = startDate.AddDays(index),
- TemperatureC = Random.Shared.Next(-20, 55),
- Summary = summaries[Random.Shared.Next(summaries.Length)]
- }).ToArray();
- }
-
- private class WeatherForecast
- {
- public DateOnly Date { get; set; }
- public int TemperatureC { get; set; }
- public string? Summary { get; set; }
- public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
- }
-}
diff --git a/RobotApp.Client/Pages/_Imports.razor b/RobotApp.Client/Pages/_Imports.razor
new file mode 100644
index 0000000..d8c136a
--- /dev/null
+++ b/RobotApp.Client/Pages/_Imports.razor
@@ -0,0 +1,16 @@
+@layout RobotApp.Client.Pages.AssemblyLayout
+@using System.Net.Http
+@using System.Net.Http.Json
+@using Microsoft.AspNetCore.Components.Authorization
+@using Microsoft.AspNetCore.Components.Forms
+@using Microsoft.AspNetCore.Components.Routing
+@using Microsoft.AspNetCore.Components.Web
+@using static Microsoft.AspNetCore.Components.Web.RenderMode
+@using static RobotApp.Client.ClientRenderMode
+@using Microsoft.AspNetCore.Components.Web.Virtualization
+@using Microsoft.JSInterop
+@using RobotApp.Client
+@using Microsoft.AspNetCore.Authorization
+@using MudBlazor
+@using RobotApp.Common.Shares
+@using RobotApp.Common.Shares.Dtos
diff --git a/RobotApp.Client/Program.cs b/RobotApp.Client/Program.cs
index 56ebe4b..6c76300 100644
--- a/RobotApp.Client/Program.cs
+++ b/RobotApp.Client/Program.cs
@@ -1,11 +1,20 @@
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using MudBlazor.Services;
+using System.Globalization;
+CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Services.AddAuthorizationCore();
builder.Services.AddCascadingAuthenticationState();
builder.Services.AddAuthenticationStateDeserialization();
-builder.Services.AddMudServices();
+
+builder.Services.AddScoped(_ => new HttpClient() { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
+builder.Services.AddMudServices(config =>
+{
+ config.SnackbarConfiguration.VisibleStateDuration = 2000;
+ config.SnackbarConfiguration.HideTransitionDuration = 500;
+ config.SnackbarConfiguration.ShowTransitionDuration = 500;
+});
await builder.Build().RunAsync();
diff --git a/RobotApp.Client/RobotApp.Client.csproj b/RobotApp.Client/RobotApp.Client.csproj
index 92168bf..c65ed05 100644
--- a/RobotApp.Client/RobotApp.Client.csproj
+++ b/RobotApp.Client/RobotApp.Client.csproj
@@ -18,4 +18,9 @@
+
+
+
+
+
diff --git a/RobotApp.Client/_Imports.razor b/RobotApp.Client/_Imports.razor
index 53fa057..449fd7f 100644
--- a/RobotApp.Client/_Imports.razor
+++ b/RobotApp.Client/_Imports.razor
@@ -5,6 +5,7 @@
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using static Microsoft.AspNetCore.Components.Web.RenderMode
+@using static RobotApp.Client.ClientRenderMode
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using RobotApp.Client
diff --git a/RobotApp.sln b/RobotApp.sln
index edd2672..258b320 100644
--- a/RobotApp.sln
+++ b/RobotApp.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 18
-VisualStudioVersion = 18.0.11018.127 d18.0
+# Visual Studio Version 17
+VisualStudioVersion = 17.14.36511.14 d17.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RobotApp", "RobotApp\RobotApp.csproj", "{BF0BB137-2EF9-4E1B-944E-9BF41C5284F7}"
EndProject
diff --git a/RobotApp/Components/App.razor b/RobotApp/Components/App.razor
index e304093..7c4ad1b 100644
--- a/RobotApp/Components/App.razor
+++ b/RobotApp/Components/App.razor
@@ -4,23 +4,23 @@
+ RobotApp
-
+
-
-
+
-
+
@@ -28,7 +28,7 @@
Not found
-
+
Không tìm thấy trang.
@@ -39,7 +39,7 @@
-
+