[Map] Render real Neshan map on shift/job detail pages
CI/CD / CI · dotnet build (push) Successful in 1m6s
CI/CD / Deploy · hamkadr (push) Successful in 1m12s

The detail pages showed a 'map coming later' placeholder. Add a read-only Neshan web map (Leaflet SDK) showing the facility marker when NeshanMapKey is set, plus a 'مسیریابی در نشان' directions link; falls back to coordinates when no key. New _NeshanMap shared partial loads the SDK and inits #facmap. Shift/Job Details models now expose MapKey via SettingsService. Coordinates are emitted with InvariantCulture so the decimal point/digits don't break JS. The facility registration picker already used Neshan; this reuses the same key.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-04 18:57:49 +03:30
parent b1e474ba33
commit 86809190e7
5 changed files with 78 additions and 7 deletions
@@ -122,6 +122,32 @@
}
}
</div>
@if (j.Facility?.Lat is not null && j.Facility?.Lng is not null)
{
var latS = j.Facility.Lat.Value.ToString(System.Globalization.CultureInfo.InvariantCulture);
var lngS = j.Facility.Lng.Value.ToString(System.Globalization.CultureInfo.InvariantCulture);
<div class="card card-pad" style="margin-top:16px;">
<h3 style="margin-top:0;">موقعیت مکانی</h3>
@if (!string.IsNullOrEmpty(Model.MapKey))
{
<div id="facmap" data-lat="@latS" data-lng="@lngS" style="height:200px; border-radius:10px; overflow:hidden; border:1px solid var(--line);"></div>
}
else
{
<div style="background:var(--primary-soft); border-radius:10px; height:140px; display:grid; place-items:center; color:var(--primary-dark); text-align:center; padding:10px;">
🗺️<br /><small class="muted" dir="ltr">@latS، @lngS</small>
</div>
}
<a class="btn btn-outline btn-block" style="margin-top:8px;" target="_blank" rel="noopener"
href="https://neshan.org/maps/@(latS),@(lngS),16z">مسیریابی در نشان</a>
</div>
}
</aside>
</div>
</div>
@if (!string.IsNullOrEmpty(Model.MapKey) && Model.Job?.Facility?.Lat is not null)
{
<partial name="_NeshanMap" model="Model.MapKey" />
}
@@ -11,14 +11,18 @@ public class DetailsModel : PageModel
{
private readonly AppDbContext _db;
private readonly InterestService _interest;
private readonly JobsMedical.Web.Services.Scraping.SettingsService _settings;
public DetailsModel(AppDbContext db, InterestService interest)
public DetailsModel(AppDbContext db, InterestService interest,
JobsMedical.Web.Services.Scraping.SettingsService settings)
{
_db = db;
_interest = interest;
_settings = settings;
}
public JobOpening? Job { get; private set; }
public string? MapKey { get; private set; }
public bool ShowContact { get; private set; }
public bool Saved { get; private set; }
public bool Reported { get; private set; }
@@ -27,6 +31,7 @@ public class DetailsModel : PageModel
{
await LoadAsync(id);
if (Job is null) return NotFound();
MapKey = (await _settings.GetAsync()).NeshanMapKey;
Reported = Request.Query["reported"] == "1";
await _interest.LogJobAsync(InterestEventType.View, id);
return Page();