update get and upsert banner

This commit is contained in:
kwan.nguyen 2025-01-09 09:02:40 +07:00
parent e7e2af2a65
commit 8a620196b5
8 changed files with 313 additions and 2 deletions

View File

@ -42,6 +42,9 @@
public const string MetadataById = "api/metadata/{0}";
public const string Log = "api/logs";
public const string Banner = "api/banners";
public const string BannerById = "api/banners/{0}";
}
}
}

View File

@ -1,4 +1,5 @@
using System;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
@ -6,8 +7,14 @@ namespace PCUT.Entities
{
public class Banner
{
[JsonProperty("_id")]
public string Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("content")]
public string Content { get; set; }
}
}

View File

@ -0,0 +1,13 @@
using Newtonsoft.Json;
namespace PCUT.Entities
{
public class UpsertBanner
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("content")]
public string Content { get; set; }
}
}

View File

@ -186,6 +186,9 @@
<Compile Include="Pages\AppOutdatedDialog.xaml.cs">
<DependentUpon>AppOutdatedDialog.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\BannerManagement\BannerUpsertDialog.xaml.cs">
<DependentUpon>BannerUpsertDialog.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\BannerManagement\BannerViewPage.xaml.cs">
<DependentUpon>BannerViewPage.xaml</DependentUpon>
</Compile>
@ -256,6 +259,7 @@
<DependentUpon>UserListPage.xaml</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ViewModels\BannerUpsertViewModel.cs" />
<Compile Include="ViewModels\BannerViewModel.cs" />
<Compile Include="ViewModels\CutDialogViewModel.cs" />
<Compile Include="ViewModels\LogViewModel.cs" />
@ -367,6 +371,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Pages\BannerManagement\BannerUpsertDialog.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Pages\BannerManagement\BannerViewPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>

View File

@ -0,0 +1,43 @@
<ContentDialog
x:Class="PCUT.Pages.BannerManagement.BannerUpsertDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:PCUT.Pages.BannerManagement"
xmlns:vm="using:PCUT.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
PrimaryButtonText="Save"
PrimaryButtonStyle="{StaticResource PrimaryDialogButton}"
PrimaryButtonCommand="{Binding Command}"
CloseButtonText="Cancel"
CloseButtonStyle="{StaticResource CloseDialogButton}"
Opened="ContentDialog_Opened">
<ContentDialog.DataContext>
<vm:BannerUpsertViewModel/>
</ContentDialog.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<TextBlock Text="Name" FontSize="20" FontFamily="/Fonts/#Rubik Medium" Margin="0 0 0 0"/>
<TextBox
Text="{Binding Name, Mode=TwoWay}"
PlaceholderText="Name">
</TextBox>
</StackPanel>
<StackPanel Grid.Row="1" Margin="0 5 0 0">
<TextBlock Text="Content" FontSize="20" FontFamily="/Fonts/#Rubik Medium"/>
<TextBox
Grid.Row="1"
Text="{Binding Content, Mode=TwoWay}"
PlaceholderText="Content"
MinHeight="64" MaxHeight="128"
TextWrapping="Wrap">
</TextBox>
</StackPanel>
</Grid>
</ContentDialog>

View File

@ -0,0 +1,38 @@
using PCUT.Entities;
using PCUT.ViewModels;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
// The Content Dialog item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
namespace PCUT.Pages.BannerManagement
{
public sealed partial class BannerUpsertDialog : ContentDialog
{
private readonly BannerUpsertViewModel _context;
public BannerUpsertDialog(string bannerId = null)
{
this.InitializeComponent();
Title = bannerId is null ? "ADD BANNER" : "EDIT BANNER";
_context = this.DataContext as BannerUpsertViewModel;
_context.Initialize(bannerId);
}
private async void ContentDialog_Opened(ContentDialog sender, ContentDialogOpenedEventArgs args)
{
await _context.LoadAsync();
}
}
}

View File

@ -0,0 +1,124 @@
using Http.Core.Exceptions;
using Http.Core;
using Http.Core.Extensions;
using PCUT.Entities.ApiResponse;
using PCUT.Entities;
using PCUT.Helpers;
using PCUT.Models;
using System;
using System.Threading.Tasks;
using System.Windows.Input;
using static Http.Core.Constants.HttpConstants;
using System.Net.Http;
using Windows.UI.Popups;
namespace PCUT.ViewModels
{
public class BannerUpsertViewModel : NotificationBase
{
private string _name;
public string Name
{
get => _name;
set { SetProperty(ref _name, value); }
}
private string _content;
public string Content
{
get => _content;
set { SetProperty(ref _content, value);}
}
private string _bannerId;
public ICommand Command { get; }
public BannerUpsertViewModel()
{
Command = new RelayCommand(async () => await UpsertBannerAsync());
}
public void Initialize(string bannerId)
{
_bannerId = bannerId;
}
public async Task LoadAsync()
{
if (_bannerId is null)
return;
using (var client = HttpClientFactory.CreateClient(ClientNames.ApiClient))
{
try
{
var response = await client.GetAsync(Api.BannerById.FormatRoute(_bannerId));
if (response.IsSuccessStatusCode)
{
var bannerData = await response.DeserializeObjectAsync<DataResponse<Banner>>();
Name = bannerData.Data.Name;
Content = bannerData.Data.Content;
}
}
catch (Exception ex) when (!(ex is AppOutdatedException)) { }
}
}
public async Task UpsertBannerAsync()
{
using (var client = HttpClientFactory.CreateClient(ClientNames.ApiClient))
{
string message;
if (_bannerId is null)
message = await AddAsync(client);
else
message = await EditAsync(client);
await new MessageDialog(message).ShowAsync();
}
}
private async Task<string> AddAsync(HttpClient client)
{
var banner = new UpsertBanner
{
Name = this.Name,
Content = this.Content
};
try
{
var response = await client.PostAsJsonAsync(Api.Banner, banner);
if (response.IsSuccessStatusCode)
return "Banner added successfully!";
else
return "Failed to add the banner!";
}
catch (Exception ex) when (!(ex is AppOutdatedException))
{
return $"error: {ex.Message}";
}
}
private async Task<string> EditAsync(HttpClient client)
{
var banner = new UpsertBanner
{
Name = this.Name,
Content = this.Content
};
try
{
var response = await client.PutAsJsonAsync(Api.BannerById.FormatRoute(_bannerId), banner);
if (response.IsSuccessStatusCode)
return "Banner edited successfully!";
else
return "Failed to edit the banner!";
}
catch (Exception ex) when (!(ex is AppOutdatedException))
{
return $"error: {ex.Message}";
}
}
}
}

View File

@ -5,13 +5,88 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Http.Core;
using Http.Core.Extensions;
using static Http.Core.Constants.HttpConstants;
using Http.Core.Exceptions;
using PCUT.Entities.ApiResponse;
using Windows.ApplicationModel.Core;
namespace PCUT.ViewModels
{
public class BannerViewModel : NotificationBase
{
public PaginationViewModel Pagination { get; } = new PaginationViewModel(withSearch: true);
public SelectableCollection<BannerModel> FilteredBanners { get; }
public SelectableCollection<BannerModel> FilteredBanners { get; } = new SelectableCollection<BannerModel>();
public BannerViewModel()
{
Pagination.TextSearched += async (sender, args) => await SearchBannerAsync(args.Text);
Pagination.PageChanged += OnPageChanged;
}
public async Task Reload()
{
await LoadBannerAsync(Pagination.Page, Pagination.PageSize, Pagination.SearchText);
}
private async void OnPageChanged(object sender, PageChangedEventArgs args)
{
await LoadBannerAsync(args.Page, args.PageSize, Pagination.SearchText);
}
private async Task SearchBannerAsync(string searchText)
{
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
{
await LoadBannerAsync(Pagination.Page, Pagination.PageSize, searchText);
});
}
private async Task LoadBannerAsync(int page, int pageSize, string searchText)
{
var url = CreateFilterUrl(page, pageSize, searchText);
using (var httpClient = HttpClientFactory.CreateClient(ClientNames.ApiClient))
{
try
{
var response = await httpClient.GetAsync(url);
if (response.IsSuccessStatusCode)
{
var apiResponse = await response.DeserializeObjectAsync<PaginationResponse<IEnumerable<BannerModel>>>();
var data = apiResponse.Data;
Pagination.Page = apiResponse.Pagination.Page;
Pagination.TotalPage = apiResponse.Pagination.TotalPages;
Pagination.TotalRecords = apiResponse.Pagination.TotalRecords;
int displayId = (apiResponse.Pagination.Page - 1) * pageSize + 1;
var banners = data.Select(banner =>
{
banner.DisplayId = displayId.ToString();
displayId++;
return banner;
});
FilteredBanners.Load(banners);
}
}
catch (Exception ex) when (!(ex is AppOutdatedException))
{
}
}
}
private string CreateFilterUrl(int page, int pageSize, string searchText)
{
var builder = PathBuilder.FromRouteTemplate(Api.Banner)
.AddQuery("page", page.ToString())
.AddQuery("pageSize", pageSize.ToString());
if (!string.IsNullOrEmpty(searchText))
{
var filter = new StringBuilder().AppendFilter("name", "cn", searchText).BuildFilter().ToString();
builder.AddQuery("filter", filter);
}
return builder.Build();
}
public class BannerModel : Banner
{