All checks were successful
CI/CD Pipeline / Build and Deploy with Docker Compose (pull_request) Successful in 9m3s
149 lines
4.6 KiB
Plaintext
149 lines
4.6 KiB
Plaintext
@using phronCare.UIBlazor.Shared.Services
|
|
@using System.Timers
|
|
@implements IAsyncDisposable
|
|
@inject IJSRuntime JS
|
|
|
|
|
|
<div class="card mt-2">
|
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
<span><i class="fas fa-map-marker-alt me-2"></i>Mapa de Ubicación</span>
|
|
<div class="d-flex gap-2">
|
|
@if (EnableAddressSearch)
|
|
{
|
|
<input @bind="SearchAddress"
|
|
@bind:event="oninput"
|
|
@onchange="OnAddressChanged"
|
|
class="form-control form-control-sm"
|
|
placeholder="Buscar dirección..."
|
|
style="width: 250px;" />
|
|
<button class="btn btn-sm btn-outline-primary" @onclick="CenterByAddress" title="Buscar" disabled="@IsSearching">
|
|
<i class="fas @(IsSearching ? "fa-spinner fa-spin" : "fa-search-location")"></i>
|
|
</button>
|
|
}
|
|
<button class="btn btn-sm btn-outline-secondary" @onclick="OpenGoogleMaps" title="Abrir en Google Maps">
|
|
<i class="fab fa-google me-1"></i>Ver en Google Maps
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="card-body p-0" style="height: 400px;">
|
|
<div id="@MapDivId" style="height: 100%; width: 100%;"></div>
|
|
</div>
|
|
</div>
|
|
|
|
@code {
|
|
private string MapDivId = string.Empty;
|
|
public static PhMap? CurrentInstance { get; private set; }
|
|
|
|
private double _latitude = -34.6037;
|
|
private double _longitude = -58.3816;
|
|
private bool _isMapInitialized = false;
|
|
private Timer? _searchDebounceTimer;
|
|
private bool IsSearching { get; set; } = false;
|
|
|
|
[Parameter]
|
|
public double Latitude
|
|
{
|
|
get => _latitude;
|
|
set => _latitude = value;
|
|
}
|
|
[Parameter]
|
|
public double Longitude
|
|
{
|
|
get => _longitude;
|
|
set => _longitude = value;
|
|
}
|
|
[Parameter] public int Zoom { get; set; } = 13;
|
|
[Parameter] public bool EnableAddressSearch { get; set; } = true;
|
|
[Parameter] public EventCallback<(double lat, double lng)> OnLocationChanged { get; set; }
|
|
|
|
private string SearchAddress { get; set; } = string.Empty;
|
|
|
|
protected override void OnInitialized()
|
|
{
|
|
MapDivId = $"map_{Guid.NewGuid()}";
|
|
CurrentInstance = this;
|
|
}
|
|
|
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
|
{
|
|
if (firstRender && !_isMapInitialized)
|
|
{
|
|
MapInterop.RegisterInstance(this);
|
|
await JS.InvokeVoidAsync("phMap.initMap", MapDivId, _latitude, _longitude, Zoom);
|
|
_isMapInitialized = true;
|
|
}
|
|
}
|
|
|
|
protected override async Task OnParametersSetAsync()
|
|
{
|
|
if (_isMapInitialized && (_latitude != Latitude || _longitude != Longitude))
|
|
{
|
|
_latitude = Latitude;
|
|
_longitude = Longitude;
|
|
await JS.InvokeVoidAsync("phMap.updateLocation", MapDivId, _latitude, _longitude);
|
|
}
|
|
}
|
|
|
|
private void OnAddressChanged(ChangeEventArgs e)
|
|
{
|
|
_searchDebounceTimer?.Stop();
|
|
_searchDebounceTimer?.Dispose();
|
|
|
|
_searchDebounceTimer = new Timer(500);
|
|
_searchDebounceTimer.Elapsed += async (s, e) =>
|
|
{
|
|
await CenterByAddress();
|
|
_searchDebounceTimer?.Stop();
|
|
};
|
|
_searchDebounceTimer.AutoReset = false;
|
|
_searchDebounceTimer.Start();
|
|
}
|
|
|
|
private async Task CenterByAddress()
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(SearchAddress))
|
|
{
|
|
IsSearching = true;
|
|
try
|
|
{
|
|
await JS.InvokeVoidAsync("phMap.searchAddress", MapDivId, SearchAddress);
|
|
}
|
|
finally
|
|
{
|
|
IsSearching = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
private async Task OpenGoogleMaps()
|
|
{
|
|
if (!IsValidLocation(_latitude, _longitude))
|
|
return;
|
|
|
|
var url = $"https://www.google.com/maps?q={_latitude.ToString(System.Globalization.CultureInfo.InvariantCulture)},{_longitude.ToString(System.Globalization.CultureInfo.InvariantCulture)}";
|
|
await JS.InvokeVoidAsync("window.open", url, "_blank");
|
|
}
|
|
|
|
private bool IsValidLocation(double lat, double lng)
|
|
{
|
|
return lat >= -90 && lat <= 90 && lng >= -180 && lng <= 180;
|
|
}
|
|
|
|
async ValueTask IAsyncDisposable.DisposeAsync()
|
|
{
|
|
_searchDebounceTimer?.Stop();
|
|
_searchDebounceTimer?.Dispose();
|
|
|
|
if (_isMapInitialized)
|
|
{
|
|
try
|
|
{
|
|
await JS.InvokeVoidAsync("phMap.destroyMap", MapDivId);
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
CurrentInstance = null;
|
|
}
|
|
}
|