Initial code commit.
This commit is contained in:
210
ui/Sufi.Demo.PeopleDirectory.UI/Client/Pages/Contacts.razor
Normal file
210
ui/Sufi.Demo.PeopleDirectory.UI/Client/Pages/Contacts.razor
Normal file
@@ -0,0 +1,210 @@
|
||||
@page "/contacts"
|
||||
|
||||
@inject HttpClient Http
|
||||
@inject IDialogService DialogService
|
||||
@inject ISnackbar Snackbar
|
||||
@inject BoomerangService Boomerang
|
||||
|
||||
<PageTitle>Contact List</PageTitle>
|
||||
|
||||
<MudGrid Class="py-4">
|
||||
<MudItem xs="12">
|
||||
<MudText Typo="Typo.h3">Contact List</MudText>
|
||||
</MudItem>
|
||||
<MudItem xs="12">
|
||||
<MudText Typo="Typo.body1">Behold! Below is the list of all registered users in this application.</MudText>
|
||||
<MudText Typo="Typo.body1" Color="Color.Error">(All data will be deleted for every 10 minutes)</MudText>
|
||||
</MudItem>
|
||||
<MudItem xs="12" Class="d-flex gap-4">
|
||||
|
||||
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@Icons.Material.Filled.Add" OnClick="OnButtonCreateClicked">Create</MudButton>
|
||||
|
||||
<MudSpacer />
|
||||
<MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.Refresh" OnClick="OnButtonRefreshClicked">Refresh</MudButton>
|
||||
|
||||
</MudItem>
|
||||
<MudItem xs="12">
|
||||
@if (contacts != null && contacts.Length > 0)
|
||||
{
|
||||
<MudTable Items="@contacts" Hover Breakpoint="Breakpoint.Sm" Loading="@loading" LoadingProgressColor="Color.Info" Class="py-3">
|
||||
<HeaderContent>
|
||||
<MudTh>Id</MudTh>
|
||||
<MudTh>Username</MudTh>
|
||||
<MudTh>Phone</MudTh>
|
||||
<MudTh>Email</MudTh>
|
||||
<MudTh>Skill Sets</MudTh>
|
||||
<MudTh>Hobby</MudTh>
|
||||
<MudTh>Action</MudTh>
|
||||
</HeaderContent>
|
||||
<RowTemplate>
|
||||
<MudTd DataLabel="Id">@context.Id</MudTd>
|
||||
<MudTd DataLabel="Username">@context.UserName</MudTd>
|
||||
<MudTd DataLabel="Phone">@context.Phone</MudTd>
|
||||
<MudTd DataLabel="Email">@context.Email</MudTd>
|
||||
<MudTd DataLabel="Skill Sets">@context.SkillSets</MudTd>
|
||||
<MudTd DataLabel="Hobby">@context.Hobby</MudTd>
|
||||
<MudTd>
|
||||
<MudTooltip Text="Edit" Placement="Placement.Top" Arrow>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Edit" OnClick="() => OnEditContactClicked(context.Id)" Color="Color.Warning" Size="Size.Small" />
|
||||
</MudTooltip>
|
||||
<MudTooltip Text="Delete" Placement="Placement.Top" Arrow>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Delete" OnClick="() => OnDeleteContactClicked(context.Id)" Color="Color.Error" Size="Size.Small" />
|
||||
</MudTooltip>
|
||||
</MudTd>
|
||||
</RowTemplate>
|
||||
<PagerContent>
|
||||
<MudTablePager />
|
||||
</PagerContent>
|
||||
</MudTable>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudText Typo="Typo.h5">No item to display. Click on the 'Create' button to add.</MudText>
|
||||
}
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
|
||||
<MudOverlay Visible="loading" DarkBackground ZIndex="9999">
|
||||
<MudProgressCircular Color="Color.Primary" Indeterminate />
|
||||
</MudOverlay>
|
||||
|
||||
@code {
|
||||
private GetAllContactsResponse[]? contacts;
|
||||
private bool loading;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await LoadTableAsync();
|
||||
|
||||
await Boomerang.AddVariableAsync("PageName", "Contacts");
|
||||
await Boomerang.SendBeaconAsync();
|
||||
}
|
||||
|
||||
private async Task LoadTableAsync()
|
||||
{
|
||||
loading = true;
|
||||
|
||||
var response = await Http.GetAsync("api/v1/contacts");
|
||||
var result = await response.ToResult<List<GetAllContactsResponse>>();
|
||||
|
||||
if (result.Succeeded)
|
||||
{
|
||||
contacts = result.Data.ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
contacts = null;
|
||||
|
||||
foreach (var message in result.Messages)
|
||||
{
|
||||
Snackbar.Add(message, Severity.Error);
|
||||
}
|
||||
}
|
||||
|
||||
loading = false;
|
||||
}
|
||||
|
||||
private async Task OnButtonRefreshClicked()
|
||||
{
|
||||
await LoadTableAsync();
|
||||
}
|
||||
|
||||
private async Task OnButtonCreateClicked()
|
||||
{
|
||||
var dialogOptions = new DialogOptions { BackdropClick = false, CloseButton = true };
|
||||
var dialog = await DialogService.ShowAsync<CreateContactDialog>("Create New Contact", dialogOptions);
|
||||
var dialogResult = await dialog.Result;
|
||||
|
||||
if (dialogResult!.Canceled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
loading = true;
|
||||
StateHasChanged();
|
||||
|
||||
var contactData = (AddEditContactCommand)dialogResult.Data!;
|
||||
var response = await Http.PostAsJsonAsync("api/v1/contacts", contactData);
|
||||
var result = await response.ToResult<int>();
|
||||
|
||||
if (result.Succeeded)
|
||||
{
|
||||
Snackbar.Add(result.Messages[0], Severity.Success);
|
||||
await LoadTableAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var message in result.Messages)
|
||||
{
|
||||
Snackbar.Add(message, Severity.Error);
|
||||
}
|
||||
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
async Task OnEditContactClicked(int id)
|
||||
{
|
||||
var dialogParams = new DialogParameters { ["Id"] = id };
|
||||
var dialogOptions = new DialogOptions { BackdropClick = false, CloseButton = true };
|
||||
var dialog = await DialogService.ShowAsync<EditContactDialog>("Edit Contact", dialogParams, dialogOptions);
|
||||
var dialogResult = await dialog.Result;
|
||||
if (dialogResult!.Canceled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
loading = true;
|
||||
StateHasChanged();
|
||||
|
||||
var contactData = (AddEditContactCommand)dialogResult.Data!;
|
||||
var response = await Http.PostAsJsonAsync("api/v1/contacts", contactData);
|
||||
var result = await response.ToResult<int>();
|
||||
|
||||
if (result.Succeeded)
|
||||
{
|
||||
Snackbar.Add(result.Messages[0], Severity.Success);
|
||||
await LoadTableAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var message in result.Messages)
|
||||
{
|
||||
Snackbar.Add(message, Severity.Error);
|
||||
}
|
||||
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
async Task OnDeleteContactClicked(int id)
|
||||
{
|
||||
var dialogResult = await DialogService.ShowMessageBox("Delete Contact", "Confirm to delete the item? This action cannot be undone.", yesText: "Delete!", cancelText: "No");
|
||||
if (dialogResult == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
loading = true;
|
||||
StateHasChanged();
|
||||
|
||||
var deleteResponse = await Http.DeleteAsync($"api/v1/contacts/{id}");
|
||||
if (deleteResponse.IsSuccessStatusCode)
|
||||
{
|
||||
var result = await deleteResponse.ToResult();
|
||||
if (result!.Succeeded)
|
||||
{
|
||||
Snackbar.Add("Contact deleted successfully.", Severity.Success);
|
||||
await LoadTableAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
Snackbar.Add(result.Messages[0], Severity.Error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Snackbar.Add("An error has occurred.", Severity.Error);
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<MudDialog>
|
||||
<DialogContent>
|
||||
<MudForm @ref="form" Model="request" @bind-IsValid="success" @bind-Errors="errors">
|
||||
<MudTextField Label="Username" Required @bind-Value="request.UserName" />
|
||||
<MudTextField Label="Email" Required @bind-Value="request.Email" />
|
||||
<MudTextField Label="Phone" Required @bind-Value="request.Phone" MaxLength="20" />
|
||||
<MudTextField Label="Skill Sets" Required @bind-Value="request.SkillSets" />
|
||||
<MudTextField Label="Hobby" Required @bind-Value="request.Hobby" />
|
||||
</MudForm>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<MudButton OnClick="Cancel">Cancel</MudButton>
|
||||
<MudButton OnClick="Submit">Ok</MudButton>
|
||||
</DialogActions>
|
||||
</MudDialog>
|
||||
|
||||
@code {
|
||||
private static readonly string[] SampleUserNames = new[]
|
||||
{
|
||||
"alex99",
|
||||
"samwise",
|
||||
"lunaStar",
|
||||
"maverick",
|
||||
"nova",
|
||||
"pixelPro",
|
||||
"kanu",
|
||||
"tay",
|
||||
"zorin",
|
||||
"echo"
|
||||
};
|
||||
private static readonly Random _rnd = new();
|
||||
|
||||
[CascadingParameter]
|
||||
private IMudDialogInstance MudDialog { get; set; } = null!;
|
||||
|
||||
private AddEditContactCommand request = new();
|
||||
private MudForm? form;
|
||||
private bool success;
|
||||
private string[] errors = { };
|
||||
|
||||
private void Cancel() => MudDialog.Cancel();
|
||||
|
||||
private async Task Submit()
|
||||
{
|
||||
await form!.Validate();
|
||||
if (!success)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MudDialog.Close(request);
|
||||
}
|
||||
|
||||
protected override Task OnInitializedAsync()
|
||||
{
|
||||
// Assign a random username from the in-memory list when the dialog opens
|
||||
request.UserName = SampleUserNames[_rnd.Next(SampleUserNames.Length)];
|
||||
return base.OnInitializedAsync();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
@using Sufi.Demo.PeopleDirectory.Application.Features.Contacts.Queries.GetById
|
||||
|
||||
@inject HttpClient Http
|
||||
|
||||
<MudDialog>
|
||||
<DialogContent>
|
||||
@if (showAlert)
|
||||
{
|
||||
<MudAlert Severity="Severity.Error">@alertMessage</MudAlert>
|
||||
}
|
||||
<MudForm @ref="form" Model="request" @bind-IsValid="success" @bind-Errors="errors">
|
||||
<MudTextField Label="Username" Required="true" @bind-Value="request.UserName" />
|
||||
<MudTextField Label="Email" Required="true" @bind-Value="request.Email" />
|
||||
<MudTextField Label="Phone" Required="true" @bind-Value="request.Phone" />
|
||||
<MudTextField Label="Skill Sets" Required="true" @bind-Value="request.SkillSets" />
|
||||
<MudTextField Label="Hobby" Required="true" @bind-Value="request.Hobby" />
|
||||
</MudForm>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<MudButton OnClick="Cancel">Cancel</MudButton>
|
||||
<MudButton OnClick="Submit">Ok</MudButton>
|
||||
</DialogActions>
|
||||
</MudDialog>
|
||||
|
||||
@code {
|
||||
[CascadingParameter]
|
||||
private IMudDialogInstance MudDialog { get; set; } = null!;
|
||||
[Parameter]
|
||||
public int Id { get; set; }
|
||||
|
||||
private AddEditContactCommand request = new();
|
||||
private MudForm? form;
|
||||
private bool success;
|
||||
private string[] errors = { };
|
||||
private bool showAlert;
|
||||
private string? alertMessage;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
var response = await Http.GetAsync($"api/v1/contacts/{Id}");
|
||||
var result = await response.ToResult<GetContactByIdResponse>();
|
||||
if (result.Succeeded)
|
||||
{
|
||||
var contact = result.Data;
|
||||
request.Id = Id;
|
||||
request.UserName = contact!.UserName;
|
||||
request.Email = contact.Email;
|
||||
request.Phone = contact.Phone;
|
||||
request.SkillSets = contact.SkillSets;
|
||||
request.Hobby = contact.Hobby;
|
||||
|
||||
showAlert = false;
|
||||
alertMessage = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
showAlert = true;
|
||||
alertMessage = string.Join(',', result.Messages);
|
||||
}
|
||||
}
|
||||
|
||||
private void Cancel() => MudDialog.Cancel();
|
||||
|
||||
private async Task Submit()
|
||||
{
|
||||
await form!.Validate();
|
||||
if (!success)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MudDialog!.Close(request);
|
||||
}
|
||||
}
|
||||
22
ui/Sufi.Demo.PeopleDirectory.UI/Client/Pages/Index.razor
Normal file
22
ui/Sufi.Demo.PeopleDirectory.UI/Client/Pages/Index.razor
Normal file
@@ -0,0 +1,22 @@
|
||||
@page "/"
|
||||
|
||||
@inject BoomerangService Boomerang
|
||||
|
||||
<PageTitle>Index - Demo App</PageTitle>
|
||||
|
||||
<MudGrid Class="py-4">
|
||||
<MudItem xs="12">
|
||||
<MudText Typo="Typo.h3">Welcome to this demo app.</MudText>
|
||||
</MudItem>
|
||||
<MudItem xs="12">
|
||||
<MudText Typo="Typo.body1">Please view the contact list page.</MudText>
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
|
||||
@code {
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
await Boomerang.AddVariableAsync("PageName", "Index");
|
||||
await Boomerang.SendBeaconAsync();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user