mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-09-30 22:23:12 +00:00
392 lines
17 KiB
Text
392 lines
17 KiB
Text
@page "/addressbook"
|
|
<Header pagename="Address Book" icon='<i class="material-icons-round opacity-10">edit_location</i>'></Header>
|
|
|
|
<style>
|
|
.pac-container.pac-logo.hdpi {
|
|
position: absolute;
|
|
z-index: 20000 !important; /* Adjust the value as needed */
|
|
}
|
|
|
|
.pac-container {
|
|
z-index: 20000 !important; /* Adjust the value as needed */
|
|
}
|
|
</style>
|
|
@using System.Linq.Dynamic.Core
|
|
@using SeaHavenIndustries.Data.IRepository;
|
|
@using System.Text.Json
|
|
@using global::Data.SeaHavenIndustries
|
|
@inject IAccountRepository _service;
|
|
|
|
<div class="row mt-3">
|
|
<div class="col-12">
|
|
<div class="card cardbg">
|
|
<div class="card-header pb-0 cardbg">
|
|
<div class="d-lg-flex">
|
|
<div>
|
|
<h5 class="mb-0 ps-3">Address Book</h5>
|
|
</div>
|
|
<div class="ms-auto my-auto d-flex flex-wrap justify-content-end text-end">
|
|
@* <div class="input-group input-group-outline w-30 ">
|
|
<input type="text" class="form-control" placeholder="Search">
|
|
</div>
|
|
<button type="button" class="btn btn-outline-primary btn-sm mb-0 mx-1" data-bs-toggle="modal" data-bs-target="#import">
|
|
<span class="fa fa-upload me-2"></span> Import CSV
|
|
</button> *@
|
|
@* <RadzenButton Text="Import XLS" Icon="grid_on" data-bs-toggle="modal" data-bs-target="#exampleModal1" class="mb-0 me-2 " style="background: #5dbf74 !important;" />
|
|
<RadzenButton Text="Export XLS" Icon="grid_on" Click="@(args => Export("excel"))" class="mb-0 me-2" />
|
|
<RadzenButton Text="Export CSV" Icon="wrap_text" Click="@(args => Export("csv"))" class="mb-0 me-2" />
|
|
*@
|
|
<button class="btn bg-gradient-info btn-sm mb-0" @onclick="()=>Edit(0)" data-bs-toggle="modal" data-bs-target="#exampleModal"> New Location</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
<RadzenDataGrid style="height: auto" @ref="grid" PagerAlwaysVisible="true" IsLoading=@isLoading ShowPagingSummary="true" Count="@count" Data="@locations" LoadData="@LoadData" AllowSorting="true" AllowFiltering="true" AllowPaging="true" PageSize="10" PagerHorizontalAlign="HorizontalAlign.Right" TItem="Locations" ColumnWidth="200px">
|
|
<Columns>
|
|
<RadzenDataGridColumn TItem="Locations" Property="Title" Title="Title" Width="120px" />
|
|
<RadzenDataGridColumn TItem="Locations" Property="Name" Title="Location" Width="120px" />
|
|
<RadzenDataGridColumn TItem="Locations" Title="Action" Context="employee" Filterable="false" Sortable="false" TextAlign="TextAlign.Center" Width="156px">
|
|
<Template Context="locations">
|
|
<RadzenButton Icon="edit" data-bs-target="#exampleModal" data-bs-toggle="modal" ButtonStyle="ButtonStyle.Success" Variant="Variant.Flat" Size="ButtonSize.Medium"
|
|
Click="@(args => Edit(locations.Id))" @onclick:stopPropagation="true">
|
|
</RadzenButton>
|
|
<RadzenButton Icon="delete" ButtonStyle="ButtonStyle.Danger" Variant="Variant.Flat" Size="ButtonSize.Medium"
|
|
Click="@(args => DeleteSweetAlert(locations.Id))" @onclick:stopPropagation="true">
|
|
</RadzenButton>
|
|
</Template>
|
|
</RadzenDataGridColumn>
|
|
</Columns>
|
|
</RadzenDataGrid>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered " role="document">
|
|
<div class="modal-content cardbg">
|
|
<div class="modal-header">
|
|
@if (model.Id == 0)
|
|
{
|
|
<h5 class="modal-title font-weight-normal" id="exampleModalLabel">Add New Location</h5>
|
|
}
|
|
else
|
|
{
|
|
<h5 class="modal-title font-weight-normal" id="exampleModalLabel">Edit Location</h5>
|
|
}
|
|
<button type="button" class="btn-close " data-bs-dismiss="modal" aria-label="Close"> X
|
|
@* <span aria-hidden="true">×</span> *@
|
|
</button>
|
|
</div>
|
|
<form method="post" @onsubmit="savedata">
|
|
<div class="modal-body">
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<label for="exampleFormControlInput1" class="form-label">Site Name:</label>
|
|
<div class="input-group input-group-outline mt-1 mb-2">
|
|
<input type="text" class="form-control" @bind="model.Title" />
|
|
</div>
|
|
</div>
|
|
<div class="col-12">
|
|
<label for="exampleFormControlInput1" class="form-label">Location:</label>
|
|
<RadzenTextBox style="width: 100%; " @ref="addressBoxRadzenTextBox" Name="BusinessAddress1" value="@model.Name" Change=@GoogleAddressAutoComplete />
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="submit" class="btn bg-gradient-info">Add</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal fade" id="exampleModal1" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel1" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered " role="document">
|
|
<div class="modal-content cardbg">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title font-weight-normal" id="exampleModalLabel">Import Locations</h5>
|
|
</div>
|
|
<form method="post" @onsubmit="savesheetdata">
|
|
<div class="modal-body">
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<label class="form-label">Upload Sheet</label>
|
|
<div class="input-group input-group-outline d-flex ">
|
|
<InputFile type="file" class="input-active form-control" id="file-upload" OnChange="@SheetUpload" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="submit" class="btn bg-gradient-info @submitbtnatrr">Add</button>
|
|
@if (issubmitting)
|
|
{
|
|
<img src="data:image/gif;base64,R0lGODlhEAAQAPIAAP///wAAAMLCwkJCQgAAAGJiYoKCgpKSkiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQJCgAAACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkECQoAAAAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkECQoAAAAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkECQoAAAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQJCgAAACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQJCgAAACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAkKAAAALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA==">
|
|
}
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@inject NorthwindService service
|
|
@inject IJSRuntime JSRuntime
|
|
@using GoogleMapsComponents.Maps.Places
|
|
@using Microsoft.AspNetCore.Components.Forms
|
|
|
|
@code {
|
|
RadzenDataGrid<Locations> grid;
|
|
int count;
|
|
int eid;
|
|
string submitbtnatrr = "";
|
|
bool issubmitting = false;
|
|
|
|
private ElementReference addressBox;
|
|
private RadzenTextBox? addressBoxRadzenTextBox;
|
|
private Autocomplete? autocomplete;
|
|
private string? placeData;
|
|
private string? formattedAddress;
|
|
IEnumerable<Locations> locations;
|
|
bool isLoading = false;
|
|
private Locations model = new Locations();
|
|
|
|
List<string> titles = new List<string> { "Sales Representative", "Vice President, Sales", "Sales Manager", "Inside Sales Coordinator" };
|
|
IEnumerable<string> selectedTitles;
|
|
|
|
async Task OnSelectedTitlesChange(object value)
|
|
{
|
|
if (selectedTitles != null && !selectedTitles.Any())
|
|
{
|
|
selectedTitles = null;
|
|
}
|
|
|
|
await grid.FirstPage();
|
|
}
|
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
|
{
|
|
if (firstRender)
|
|
{
|
|
await JSRuntime.InvokeVoidAsync("initScripts");
|
|
addressBox = addressBoxRadzenTextBox.Element;
|
|
await SetupGoogleAddressAutoComplete();
|
|
}
|
|
}
|
|
async Task Reset()
|
|
{
|
|
grid.Reset(true);
|
|
await grid.FirstPage(true);
|
|
}
|
|
protected async Task Edit(int id)
|
|
{
|
|
if (id != 0)
|
|
{
|
|
eid = id;
|
|
model = await _service.GetLocationById(id);
|
|
formattedAddress = model.Name;
|
|
}
|
|
else
|
|
{
|
|
model = new Locations();
|
|
formattedAddress = null;
|
|
}
|
|
}
|
|
protected async Task savesheetdata()
|
|
{
|
|
//model.Name = formattedAddress;
|
|
issubmitting = true;
|
|
|
|
submitbtnatrr = "disabled";
|
|
|
|
var res = await _service.ImportLocation(file);
|
|
if (res == "success")
|
|
{
|
|
await ShowSweetAlert("Sucessfully Saved Data", "success");
|
|
// modelList = (await _service.GetLocations())
|
|
// .OrderBy(location => location.Title)
|
|
// .ToList();
|
|
locations = await _service.GetLocationsiqueryable();
|
|
//await LoadData(null);
|
|
await JSRuntime.InvokeVoidAsync("location.reload");
|
|
|
|
submitbtnatrr = "";
|
|
issubmitting = false;
|
|
}
|
|
else
|
|
{
|
|
await ShowSweetAlert(res, "error");
|
|
submitbtnatrr = "";
|
|
issubmitting = false;
|
|
|
|
}
|
|
}
|
|
protected async Task savedata()
|
|
{
|
|
//model.Name = formattedAddress;
|
|
var res = await _service.AddLocation(model);
|
|
if (res == "success")
|
|
{
|
|
await ShowSweetAlert("Sucessfully Saved Data", "success");
|
|
locations = await _service.GetLocationsiqueryable();
|
|
grid.Reload();
|
|
StateHasChanged();
|
|
}
|
|
else
|
|
{
|
|
await ShowSweetAlert(res, "error");
|
|
}
|
|
}
|
|
private async Task ShowSweetAlert(string title, string icon)
|
|
{
|
|
// Display a SweetAlert dialog
|
|
await JSRuntime.InvokeVoidAsync("Swal.fire", new
|
|
{
|
|
toast = true,
|
|
showConfirmButton = false,
|
|
timer = 3000,
|
|
title = title,
|
|
icon = icon,
|
|
position = "top-end"
|
|
});
|
|
await JSRuntime.InvokeVoidAsync("closemodal");
|
|
}
|
|
private async Task GoogleAddressAutoComplete()
|
|
{
|
|
|
|
System.Threading.Thread.Sleep(500); // this is a hack. with no wait place was null first time
|
|
|
|
var place = await this.autocomplete.GetPlace();
|
|
var placeDataTest = JsonSerializer.Serialize(place);
|
|
if (place?.AddressComponents == null)
|
|
{
|
|
// this.message = "No results available for " + place?.Name;
|
|
}
|
|
else
|
|
{
|
|
model.Name = place.FormattedAddress;
|
|
|
|
var placeId = place.PlaceId;
|
|
var streetNumber = place.AddressComponents.FirstOrDefault(a => a.Types != null && a.Types.Contains("street_number"))?.LongName;
|
|
var street = place.AddressComponents.FirstOrDefault(a => a.Types != null && (a.Types.Contains("route") || a.Types.Contains("street_address")))?.LongName;
|
|
var city = place.AddressComponents.FirstOrDefault(a => a.Types != null && (a.Types.Contains("locality") || a.Types.Contains("neighborhood")))?.LongName;
|
|
var state = place.AddressComponents.FirstOrDefault(a => a.Types != null && a.Types.Contains("administrative_area_level_1"))?.LongName;
|
|
var country = place.AddressComponents.FirstOrDefault(a => a.Types != null && a.Types.Contains("country"))?.LongName;
|
|
var postcode = place.AddressComponents.FirstOrDefault(a => a.Types != null && a.Types.Contains("postal_code"))?.LongName;
|
|
formattedAddress = place.FormattedAddress;
|
|
// model.Title = place.AddressComponents.FirstOrDefault()?.LongName;
|
|
placeData = JsonSerializer.Serialize(place);
|
|
}
|
|
}
|
|
|
|
private async Task SetupGoogleAddressAutoComplete()
|
|
{
|
|
this.autocomplete = await Autocomplete.CreateAsync(JSRuntime, addressBox, new AutocompleteOptions
|
|
{
|
|
StrictBounds = false,
|
|
});
|
|
await this.autocomplete.SetFields(new[] { "address_components", "place_id", "formatted_address" });
|
|
}
|
|
private async Task DeleteSweetAlert(int val)
|
|
{
|
|
var result = await JSRuntime.InvokeAsync<JsonElement>("Swal.fire", new
|
|
{
|
|
html = "<div style='text-align: center;'><img src='./assets/img/delete icon.png' style='width: 100px;' /></div>" +
|
|
"<h4>Are you sure you want to delete</h4>" +
|
|
"<p style='font-size: 18px;'>\"Nicolas Alvarado\"</p>",
|
|
type = "warning",
|
|
showCancelButton = true,
|
|
customClass = new
|
|
{
|
|
confirmButton = "btn btn-success m-1",
|
|
cancelButton = "btn btn-danger m-1"
|
|
},
|
|
buttonsStyling = false,
|
|
confirmButtonText = "Yes",
|
|
cancelButtonText = "No"
|
|
});
|
|
|
|
if (result.TryGetProperty("isConfirmed", out var isConfirmedProperty) && isConfirmedProperty.GetBoolean())
|
|
{
|
|
// Call your delete API here
|
|
var response = await _service.DeleteLocation(val);
|
|
if (response == "success")
|
|
{
|
|
await JSRuntime.InvokeVoidAsync("Swal.fire", new
|
|
{
|
|
icon = "success",
|
|
title = "Deleted!",
|
|
text = "Data has been deleted.",
|
|
type = "primary",
|
|
showCancelButton = false,
|
|
customClass = new
|
|
{
|
|
confirmButton = "btn btn-success",
|
|
cancelButton = "btn btn-danger"
|
|
},
|
|
buttonsStyling = false,
|
|
confirmButtonText = "Ok"
|
|
});
|
|
locations = await _service.GetLocationsiqueryable();
|
|
await JSRuntime.InvokeVoidAsync("location.reload");
|
|
|
|
|
|
// await JSRuntime.InvokeVoidAsync("location.reload");
|
|
}
|
|
else
|
|
{
|
|
await JSRuntime.InvokeVoidAsync("Swal.fire", new
|
|
{
|
|
title = "Not Deleted!",
|
|
text = "Unsuccessful! Cannot delete this.",
|
|
type = "danger"
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
async Task LoadData(LoadDataArgs args)
|
|
{
|
|
isLoading = true;
|
|
|
|
await Task.Yield();
|
|
|
|
// This demo is using https://dynamic-linq.net
|
|
var query = await _service.GetLocationsiqueryable();
|
|
|
|
if (!string.IsNullOrEmpty(args.Filter))
|
|
{
|
|
// Filter via the Where method
|
|
query = query.Where(args.Filter);
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(args.OrderBy))
|
|
{
|
|
// Sort via the OrderBy method
|
|
query = query.OrderBy(args.OrderBy);
|
|
}
|
|
|
|
// Important!!! Make sure the Count property of RadzenDataGrid is set.
|
|
count = query.Count();
|
|
|
|
// Perform paging via Skip and Take.
|
|
locations = query.Skip(args.Skip.Value).Take(args.Top.Value).ToList();
|
|
|
|
isLoading = false;
|
|
}
|
|
public void Export(string type)
|
|
{
|
|
service.Export("locations", type, new Query()
|
|
{
|
|
OrderBy = grid.Query.OrderBy,
|
|
Filter = grid.Query.Filter,
|
|
Select = string.Join(",", grid.ColumnsCollection.Where(c => c.GetVisible() && !string.IsNullOrEmpty(c.Property))
|
|
.Select(c => c.Property.Contains(".") ? $"{c.Property} as {c.Property.Replace(".", "_")}" : c.Property))
|
|
});
|
|
}
|
|
private IBrowserFile file;
|
|
|
|
private async Task SheetUpload(InputFileChangeEventArgs e)
|
|
{
|
|
// Use IFormFile as needed
|
|
file = e.File;
|
|
|
|
}
|
|
}
|