@page "{id:int}" @model JobsMedical.Web.Pages.Shifts.DetailsModel @{ var s = Model.Shift!; var f = s.Facility!; var hasFac = JobsMedical.Web.Services.SeoJsonLd.HasRealEmployer(f); // false for the «نامشخص» placeholder var shiftContacts = (s.Contacts ?? new List()).ToList(); // Map: prefer the listing's own approx coords (aggregated ads) then the facility's. Aggregated = // approximate → shown as an area circle with a disclaimer, never a precise pin. var mapLat = s.Lat ?? f.Lat; var mapLng = s.Lng ?? f.Lng; var mapApprox = s.Source == JobsMedical.Web.Models.ShiftSource.Aggregated; ViewData["Title"] = hasFac ? $"شیفت {s.SpecialtyRequired} - {f.Name}" : $"شیفت {s.SpecialtyRequired} — {f.City?.Name}"; ViewData["Description"] = hasFac ? $"شیفت {s.SpecialtyRequired} در {f.Name}، {f.City?.Name}، تاریخ {JalaliDate.ToLongDate(s.Date)} از ساعت {JalaliDate.Time(s.StartTime)}." : $"شیفت {s.SpecialtyRequired} در {f.City?.Name}، تاریخ {JalaliDate.ToLongDate(s.Date)} از ساعت {JalaliDate.Time(s.StartTime)}."; // Past/filled shifts shouldn't stay in the index as dead pages. if (s.Status != JobsMedical.Web.Models.ShiftStatus.Open || s.Date < DateOnly.FromDateTime(DateTime.UtcNow)) ViewData["NoIndex"] = true; var (badgeClass, typeLabel) = s.ShiftType switch { ShiftType.Day => ("badge-day", "شیفت صبح"), ShiftType.Evening => ("badge-evening", "شیفت عصر"), ShiftType.Night => ("badge-night", "شیفت شب"), _ => ("badge-oncall", "آنکال"), }; var crumbs = new List { new("خانه", "/"), new("شیفت‌ها", "/Shifts") }; if (s.Role is not null) crumbs.Add(new(s.Role.Name, "/شیفت/" + JobsMedical.Web.Services.SeoSlug.Of(s.Role.Name))); crumbs.Add(new(JobsMedical.Web.Services.SeoJsonLd.HasRealEmployer(f) ? f.Name : "جزئیات شیفت", null)); }
@typeLabel @if (f.IsVerified) { ✓ مرکز تأیید شده }

@s.SpecialtyRequired@(hasFac ? " — " + f.Name : "")

📍 @f.City?.Name @(string.IsNullOrEmpty(f.Address) ? "" : "، " + f.Address)

@if (Model.ShowContact) {

✓ راه‌های ارتباطی

@if (shiftContacts.Count > 0) { @* Numbers from THIS ad (aggregated) — the correct, per-listing contacts. *@ } else if (JobsMedical.Web.Services.SeoJsonLd.HasRealEmployer(f) && (!string.IsNullOrEmpty(f.Phone) || !string.IsNullOrEmpty(f.BaleId))) { @if (!string.IsNullOrEmpty(f.Phone)) {
📞 تلفن مرکز@f.Phone تماس
} @if (!string.IsNullOrEmpty(f.BaleId)) {
💬 بله@f.BaleId باز کردن
} } else {

شماره‌ای ثبت نشده است.

}
}

جزئیات شیفت

تاریخ@JalaliDate.WeekDayName(s.Date)، @JalaliDate.ToLongDate(s.Date)
ساعت@JalaliDate.Time(s.StartTime) تا @JalaliDate.Time(s.EndTime)
مدت@JalaliDate.ToPersianDigits(s.DurationHours.ToString("0.#")) ساعت
نقش مورد نیاز@(s.Role?.Name ?? s.SpecialtyRequired)
@if (s.GenderRequirement != Gender.Any) {
جنسیت@JalaliDate.GenderLabel(s.GenderRequirement)
}
پرداخت@JalaliDate.PayLabel(s.PayType, s.PayAmount, s.SharePercent)
بازه ساعت کاری در شبانه‌روز
@if (!string.IsNullOrEmpty(s.Description)) {

توضیحات

@s.Description

} @if (hasFac && Model.MoreAtFacility.Count > 0) {

شیفت‌های دیگر این مرکز

@foreach (var more in Model.MoreAtFacility) { }
}
@* Sticky bottom action bar — mobile only. Always-reachable primary action (native-app feel). *@
@if (!string.IsNullOrEmpty(Model.MapKey) && mapLat is not null) { } @section Head { @{ var bu = $"{ViewContext.HttpContext.Request.Scheme}://{ViewContext.HttpContext.Request.Host}"; } @Html.Raw("") @* Only for a real named employer — Google for Jobs rejects a placeholder hiringOrganization. *@ @if (JobsMedical.Web.Services.SeoJsonLd.HasRealEmployer(f)) { @Html.Raw("") } }