2026-06-08 08:01:12 +03:30
|
|
|
@page "{id:int}"
|
|
|
|
|
@model JobsMedical.Web.Pages.Talent.DetailsModel
|
|
|
|
|
@{
|
|
|
|
|
var t = Model.Item!;
|
|
|
|
|
var heading = string.IsNullOrWhiteSpace(t.PersonName) ? (t.Role?.Name ?? "آماده به کار") : t.PersonName!;
|
|
|
|
|
ViewData["Title"] = $"{heading} — آماده به کار";
|
|
|
|
|
// Personal contact info: keep this page out of search indexes.
|
|
|
|
|
ViewData["NoIndex"] = true;
|
|
|
|
|
string comp;
|
|
|
|
|
if (t.PayType == JobsMedical.Web.Models.PayType.Percentage && t.SharePercent is int sp)
|
|
|
|
|
comp = $"{JalaliDate.ToPersianDigits(sp.ToString())}٪ سهم درآمد";
|
|
|
|
|
else if (t.PayAmount is long pa && pa > 0)
|
|
|
|
|
comp = JalaliDate.Toman(pa) + " مدنظر";
|
|
|
|
|
else
|
|
|
|
|
comp = "توافقی";
|
|
|
|
|
string? telHref = null;
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(t.Phone))
|
|
|
|
|
{
|
|
|
|
|
var digits = new string(t.Phone.Where(char.IsDigit).ToArray());
|
|
|
|
|
if (digits.Length >= 7) telHref = "tel:" + digits;
|
|
|
|
|
}
|
2026-06-08 09:05:34 +03:30
|
|
|
// Only Divar is surfaced as a fallback source (and only when no number was extracted).
|
|
|
|
|
// We never name other crawl sources (medjobs/telegram/…) publicly.
|
|
|
|
|
bool isDivar = !string.IsNullOrWhiteSpace(t.SourceUrl)
|
|
|
|
|
&& System.Uri.TryCreate(t.SourceUrl, UriKind.Absolute, out var su) && su.Host.Contains("divar");
|
2026-06-08 08:01:12 +03:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
<div class="page-head">
|
|
|
|
|
<div class="container">
|
|
|
|
|
<h1>@heading</h1>
|
|
|
|
|
<p class="muted">آماده همکاری @(t.Role is not null ? "— " + t.Role.Name : "") · 📍 @t.City?.Name@(t.District?.Name is not null ? "، " + t.District.Name : (t.AreaNote is not null ? "، " + t.AreaNote : ""))</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="container section">
|
|
|
|
|
<div class="detail-grid">
|
|
|
|
|
<div>
|
|
|
|
|
<div class="card card-pad">
|
|
|
|
|
<div class="row" style="gap:8px; flex-wrap:wrap;">
|
|
|
|
|
@if (t.Role is not null) { <span class="badge badge-type">@t.Role.Name</span> }
|
|
|
|
|
<span class="badge badge-talent">آماده به کار</span>
|
|
|
|
|
@if (t.YearsExperience is int yrs && yrs > 0) { <span class="badge badge-day">@JalaliDate.ToPersianDigits(yrs.ToString()) سال سابقه</span> }
|
|
|
|
|
@if (t.IsLicensed) { <span class="badge badge-verified">پروانهدار</span> }
|
|
|
|
|
@if (t.Gender != JobsMedical.Web.Models.Gender.Any) { <span class="badge badge-gender">@JalaliDate.GenderLabel(t.Gender)</span> }
|
|
|
|
|
@if (t.Availability is JobsMedical.Web.Models.EmploymentType emp)
|
|
|
|
|
{
|
|
|
|
|
<span class="badge badge-job">@(emp switch {
|
|
|
|
|
JobsMedical.Web.Models.EmploymentType.FullTime => "تماموقت",
|
|
|
|
|
JobsMedical.Web.Models.EmploymentType.PartTime => "پارهوقت",
|
|
|
|
|
JobsMedical.Web.Models.EmploymentType.Contract => "قراردادی",
|
|
|
|
|
_ => "طرح" })</span>
|
|
|
|
|
}
|
|
|
|
|
</div>
|
|
|
|
|
@if (!string.IsNullOrWhiteSpace(t.AreaNote))
|
|
|
|
|
{
|
|
|
|
|
<p style="margin:12px 0 0;"><strong>محدوده کاری:</strong> @t.AreaNote</p>
|
|
|
|
|
}
|
|
|
|
|
<p style="margin:12px 0 0;"><strong>دستمزد مدنظر:</strong> @comp</p>
|
|
|
|
|
@if (!string.IsNullOrWhiteSpace(t.Description))
|
|
|
|
|
{
|
|
|
|
|
<hr style="border:none; border-top:1px solid var(--line); margin:16px 0;" />
|
|
|
|
|
<p style="white-space:pre-wrap; margin:0;">@t.Description</p>
|
|
|
|
|
}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<aside>
|
|
|
|
|
<div class="card card-pad">
|
2026-06-08 11:10:19 +03:30
|
|
|
<h3 style="margin-top:0;">راههای ارتباطی</h3>
|
|
|
|
|
@{ var contacts = (t.Contacts ?? new List<JobsMedical.Web.Models.ContactMethod>()).OrderBy(c => c.SortOrder).ToList(); }
|
|
|
|
|
@if (contacts.Count > 0)
|
|
|
|
|
{
|
2026-06-08 11:33:41 +03:30
|
|
|
<div class="contact-reveal">
|
|
|
|
|
@foreach (var c in contacts)
|
2026-06-08 11:10:19 +03:30
|
|
|
{
|
2026-06-08 11:33:41 +03:30
|
|
|
var href = JobsMedical.Web.Services.ContactInfo.Href(c.Type, c.Value);
|
|
|
|
|
var label = JobsMedical.Web.Services.ContactInfo.Label(c.Type);
|
|
|
|
|
var icon = JobsMedical.Web.Services.ContactInfo.Icon(c.Type);
|
|
|
|
|
var cls = c.Type is JobsMedical.Web.Models.ContactType.Mobile or JobsMedical.Web.Models.ContactType.Phone ? "btn-accent" : "btn-outline";
|
|
|
|
|
<div class="contact-row">
|
|
|
|
|
<span class="c-meta"><span class="c-type">@icon @label</span><span class="c-val" dir="ltr">@c.Value</span></span>
|
|
|
|
|
@if (href is not null)
|
|
|
|
|
{
|
|
|
|
|
<a class="btn @cls" href="@href" target="_blank" rel="nofollow noopener">باز کردن</a>
|
|
|
|
|
}
|
|
|
|
|
</div>
|
2026-06-08 11:10:19 +03:30
|
|
|
}
|
2026-06-08 11:33:41 +03:30
|
|
|
</div>
|
2026-06-08 11:10:19 +03:30
|
|
|
}
|
|
|
|
|
else if (telHref is not null)
|
2026-06-08 08:01:12 +03:30
|
|
|
{
|
|
|
|
|
<a href="@telHref" class="btn btn-accent btn-block btn-lg" dir="ltr">📞 @t.Phone</a>
|
|
|
|
|
}
|
2026-06-08 09:05:34 +03:30
|
|
|
else if (isDivar)
|
2026-06-08 08:01:12 +03:30
|
|
|
{
|
2026-06-08 09:05:34 +03:30
|
|
|
@* Divar hides the number behind a login-gated reveal — point to the original ad. *@
|
2026-06-09 22:01:04 +03:30
|
|
|
<p class="muted" style="margin-top:0;">مشاهده شماره در وبسایت دیوار</p>
|
2026-06-08 09:05:34 +03:30
|
|
|
<a href="@t.SourceUrl" target="_blank" rel="nofollow noopener" class="btn btn-accent btn-block btn-lg">مشاهده شماره در دیوار ↗</a>
|
|
|
|
|
<p class="muted" style="font-size:12px; margin:10px 0 0;">برای دریافت شماره به آگهی اصلی در دیوار مراجعه کن.</p>
|
2026-06-08 08:01:12 +03:30
|
|
|
}
|
2026-06-08 08:36:12 +03:30
|
|
|
else
|
2026-06-08 08:01:12 +03:30
|
|
|
{
|
2026-06-08 08:36:12 +03:30
|
|
|
<p class="muted">شماره تماس ثبت نشده است.</p>
|
2026-06-08 08:01:12 +03:30
|
|
|
}
|
|
|
|
|
</div>
|
|
|
|
|
</aside>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|