Initial commit — Hamkadr (همکادر) healthcare-staffing marketplace
ASP.NET Core 10 Razor Pages + PostgreSQL/EF Core. RTL Persian, Jalali dates, self-hosted Vazirmatn, teal/coral brand. Features: - Shift listings: browse/filter (city, district, role, type, pay), weekly Jalali calendar, detail + interest handoff, near-me distance sort - Hiring (استخدام) listings with employment type + salary range - Pattern-engine recommendations + anonymous interest tracking (visitor cookie) - Heuristic Persian listing-parser + admin queue (raw channel post → shift/job) - Phone-OTP cookie auth + visitor-history linking + profile Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
@page "{id:int}"
|
||||
@model JobsMedical.Web.Pages.Admin.ReviewModel
|
||||
@{
|
||||
ViewData["Title"] = "بررسی و انتشار آگهی";
|
||||
var r = Model.Raw!;
|
||||
}
|
||||
|
||||
<div class="page-head">
|
||||
<div class="container"><h1>بررسی و انتشار آگهی</h1><p class="muted">منبع: @r.SourceChannel</p></div>
|
||||
</div>
|
||||
|
||||
<div class="container section">
|
||||
<div class="detail-grid">
|
||||
<div>
|
||||
<div class="card card-pad">
|
||||
<h3 style="margin-top:0;">متن خام</h3>
|
||||
<p style="white-space:pre-wrap; margin:0;">@r.RawText</p>
|
||||
</div>
|
||||
|
||||
@if (Model.Parsed is not null)
|
||||
{
|
||||
<div class="card card-pad" style="margin-top:16px;">
|
||||
<h3 style="margin-top:0;">🤖 تشخیص خودکار (پارسر)</h3>
|
||||
<div class="rec-reasons">
|
||||
@foreach (var note in Model.Parsed.Notes)
|
||||
{
|
||||
<span class="rec-reason">• @note</span>
|
||||
}
|
||||
@if (Model.Parsed.CityName is not null) { <span class="rec-reason">• شهر: @Model.Parsed.CityName</span> }
|
||||
@if (Model.Parsed.DistrictName is not null) { <span class="rec-reason">• محله: @Model.Parsed.DistrictName</span> }
|
||||
@if (Model.Parsed.Phone is not null) { <span class="rec-reason">• تلفن: @Model.Parsed.Phone</span> }
|
||||
</div>
|
||||
<p class="muted" style="font-size:12px; margin-bottom:0;">اینها فقط پیشنهاد هستند؛ قبل از انتشار بررسی و اصلاح کن.</p>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<aside>
|
||||
<form method="post" class="card card-pad">
|
||||
<div class="filter-group">
|
||||
<label>نوع آگهی</label>
|
||||
<select name="Kind" id="kindSelect">
|
||||
<option value="0" selected="@(Model.Kind == JobsMedical.Web.Models.ListingKind.Shift)">شیفت</option>
|
||||
<option value="1" selected="@(Model.Kind == JobsMedical.Web.Models.ListingKind.Job)">استخدام</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-group">
|
||||
<label>مرکز درمانی</label>
|
||||
<select name="FacilityId">
|
||||
@foreach (var f in Model.Facilities)
|
||||
{
|
||||
<option value="@f.Id">@f.Name — @f.City?.Name</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-group">
|
||||
<label>نقش</label>
|
||||
<select name="RoleId">
|
||||
@foreach (var role in Model.Roles)
|
||||
{
|
||||
<option value="@role.Id" selected="@(Model.RoleId == role.Id)">@role.Name</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div id="shiftFields">
|
||||
<div class="filter-group">
|
||||
<label>تاریخ شیفت (میلادی)</label>
|
||||
<input type="date" name="ShiftDate" value="@Model.ShiftDate.ToString("yyyy-MM-dd")" dir="ltr" />
|
||||
</div>
|
||||
<div class="filter-group">
|
||||
<label>نوع شیفت</label>
|
||||
<select name="ShiftType">
|
||||
<option value="0" selected="@(Model.ShiftType == JobsMedical.Web.Models.ShiftType.Day)">صبح</option>
|
||||
<option value="1" selected="@(Model.ShiftType == JobsMedical.Web.Models.ShiftType.Evening)">عصر</option>
|
||||
<option value="2" selected="@(Model.ShiftType == JobsMedical.Web.Models.ShiftType.Night)">شب</option>
|
||||
<option value="3" selected="@(Model.ShiftType == JobsMedical.Web.Models.ShiftType.OnCall)">آنکال</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-group" style="display:flex; gap:8px;">
|
||||
<div style="flex:1;"><label>شروع</label><input type="time" name="StartTime" value="@Model.StartTime.ToString("HH:mm")" dir="ltr" /></div>
|
||||
<div style="flex:1;"><label>پایان</label><input type="time" name="EndTime" value="@Model.EndTime.ToString("HH:mm")" dir="ltr" /></div>
|
||||
</div>
|
||||
<div class="filter-group">
|
||||
<label>حقوق هر شیفت (تومان)</label>
|
||||
<input type="number" name="PayAmount" value="@Model.PayAmount" dir="ltr" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="jobFields" style="display:none;">
|
||||
<div class="filter-group">
|
||||
<label>عنوان موقعیت</label>
|
||||
<input type="text" name="Title" value="@Model.Title" />
|
||||
</div>
|
||||
<div class="filter-group">
|
||||
<label>نوع همکاری</label>
|
||||
<select name="EmploymentType">
|
||||
<option value="0" selected="@(Model.EmploymentType == JobsMedical.Web.Models.EmploymentType.FullTime)">تماموقت</option>
|
||||
<option value="1" selected="@(Model.EmploymentType == JobsMedical.Web.Models.EmploymentType.PartTime)">پارهوقت</option>
|
||||
<option value="2" selected="@(Model.EmploymentType == JobsMedical.Web.Models.EmploymentType.Contract)">قراردادی</option>
|
||||
<option value="3" selected="@(Model.EmploymentType == JobsMedical.Web.Models.EmploymentType.Plan)">طرح</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-group" style="display:flex; gap:8px;">
|
||||
<div style="flex:1;"><label>حقوق از</label><input type="number" name="SalaryMin" value="@Model.SalaryMin" dir="ltr" /></div>
|
||||
<div style="flex:1;"><label>تا</label><input type="number" name="SalaryMax" value="@Model.SalaryMax" dir="ltr" /></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="filter-group">
|
||||
<label style="display:flex; align-items:center; gap:8px; font-weight:600;">
|
||||
<input type="checkbox" name="Negotiable" value="true" style="width:auto;" checked="@Model.Negotiable" /> توافقی
|
||||
</label>
|
||||
</div>
|
||||
<div class="filter-group">
|
||||
<label>توضیحات</label>
|
||||
<textarea name="Description" rows="3">@Model.Description</textarea>
|
||||
</div>
|
||||
|
||||
<button type="submit" asp-page-handler="Publish" asp-route-id="@r.Id" class="btn btn-accent btn-block btn-lg">انتشار</button>
|
||||
<button type="submit" asp-page-handler="Discard" asp-route-id="@r.Id" class="btn btn-outline btn-block" style="margin-top:8px;">رد و حذف از صف</button>
|
||||
</form>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
<script>
|
||||
var kind = document.getElementById('kindSelect');
|
||||
function toggleKind() {
|
||||
var isJob = kind.value === '1';
|
||||
document.getElementById('jobFields').style.display = isJob ? 'block' : 'none';
|
||||
document.getElementById('shiftFields').style.display = isJob ? 'none' : 'block';
|
||||
}
|
||||
kind.addEventListener('change', toggleKind);
|
||||
toggleKind();
|
||||
</script>
|
||||
}
|
||||
Reference in New Issue
Block a user