Add facility verification (admin verify/unverify → verified badge)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -43,6 +43,7 @@ Then open the URL printed in the console (e.g. http://localhost:5020).
|
|||||||
| `/Account/Profile` | پروفایل: شیفتها/موقعیتهای ذخیرهشده و اعلام تمایلها |
|
| `/Account/Profile` | پروفایل: شیفتها/موقعیتهای ذخیرهشده و اعلام تمایلها |
|
||||||
| `/Admin` | پنل مدیریت (نقش Admin): صف آگهیهای خام |
|
| `/Admin` | پنل مدیریت (نقش Admin): صف آگهیهای خام |
|
||||||
| `/Admin/Review/{id}` | بررسی خودکار (پارسر) و انتشار آگهی بهصورت شیفت یا استخدام |
|
| `/Admin/Review/{id}` | بررسی خودکار (پارسر) و انتشار آگهی بهصورت شیفت یا استخدام |
|
||||||
|
| `/Admin/Facilities` | تأیید/لغو تأیید مراکز درمانی (نشان «تأیید شده») |
|
||||||
| `/Employer` | **پنل کارفرما**: مراکز من + شمار شیفت/استخدام/متقاضی |
|
| `/Employer` | **پنل کارفرما**: مراکز من + شمار شیفت/استخدام/متقاضی |
|
||||||
| `/Employer/RegisterFacility` | ثبت مرکز درمانی (خودسرویس → نقش FacilityAdmin) |
|
| `/Employer/RegisterFacility` | ثبت مرکز درمانی (خودسرویس → نقش FacilityAdmin) |
|
||||||
| `/Employer/PostShift`، `/PostJob` | انتشار شیفت یا موقعیت استخدامی |
|
| `/Employer/PostShift`، `/PostJob` | انتشار شیفت یا موقعیت استخدامی |
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
@page
|
||||||
|
@model JobsMedical.Web.Pages.Admin.FacilitiesModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "مدیریت مراکز درمانی";
|
||||||
|
string TypeLabel(FacilityType t) => t switch
|
||||||
|
{
|
||||||
|
FacilityType.Hospital => "بیمارستان",
|
||||||
|
FacilityType.Clinic => "کلینیک",
|
||||||
|
_ => "درمانگاه",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="page-head">
|
||||||
|
<div class="container">
|
||||||
|
<h1>تأیید مراکز درمانی</h1>
|
||||||
|
<p class="muted">
|
||||||
|
<a asp-page="/Admin/Index">← صف آگهیها</a>
|
||||||
|
· @JalaliDate.ToPersianDigits(Model.Pending.Count.ToString()) مرکز در انتظار تأیید
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container section">
|
||||||
|
<h2 style="font-size:20px;">در انتظار تأیید</h2>
|
||||||
|
@if (Model.Pending.Count == 0)
|
||||||
|
{
|
||||||
|
<div class="card empty-state">مرکزی در انتظار تأیید نیست.</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (var f in Model.Pending)
|
||||||
|
{
|
||||||
|
<div class="card card-pad" style="margin-bottom:10px;">
|
||||||
|
<div class="row" style="display:flex; justify-content:space-between; align-items:center; gap:10px;">
|
||||||
|
<div>
|
||||||
|
<strong>@f.Name</strong> — @TypeLabel(f.Type)
|
||||||
|
<div class="muted" style="font-size:13px;">
|
||||||
|
📍 @f.City?.Name@(f.District is not null ? "، " + f.District.Name : "")
|
||||||
|
@if (f.OwnerUser is not null) { <text> · مالک: <span dir="ltr">@JalaliDate.ToPersianDigits(f.OwnerUser.Phone)</span></text> }
|
||||||
|
@if (!string.IsNullOrEmpty(f.Phone)) { <text> · تلفن: <span dir="ltr">@JalaliDate.ToPersianDigits(f.Phone)</span></text> }
|
||||||
|
</div>
|
||||||
|
@if (!string.IsNullOrEmpty(f.Address)) { <div class="muted" style="font-size:13px;">@f.Address</div> }
|
||||||
|
</div>
|
||||||
|
<form method="post">
|
||||||
|
<button asp-page-handler="Verify" asp-route-id="@f.Id" class="btn btn-accent" style="white-space:nowrap;">✓ تأیید</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<h2 style="font-size:20px; margin-top:30px;">مراکز تأییدشده</h2>
|
||||||
|
@if (Model.Verified.Count == 0)
|
||||||
|
{
|
||||||
|
<div class="card empty-state">هنوز مرکزی تأیید نشده.</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (var f in Model.Verified)
|
||||||
|
{
|
||||||
|
<div class="card card-pad" style="margin-bottom:10px;">
|
||||||
|
<div class="row" style="display:flex; justify-content:space-between; align-items:center; gap:10px;">
|
||||||
|
<div>
|
||||||
|
<strong>@f.Name</strong> <span class="badge badge-verified">✓ تأیید شده</span>
|
||||||
|
<div class="muted" style="font-size:13px;">📍 @f.City?.Name — @TypeLabel(f.Type)</div>
|
||||||
|
</div>
|
||||||
|
<form method="post">
|
||||||
|
<button asp-page-handler="Unverify" asp-route-id="@f.Id" class="btn btn-outline" style="white-space:nowrap;">لغو تأیید</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
using JobsMedical.Web.Data;
|
||||||
|
using JobsMedical.Web.Models;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace JobsMedical.Web.Pages.Admin;
|
||||||
|
|
||||||
|
[Authorize(Roles = "Admin")]
|
||||||
|
public class FacilitiesModel : PageModel
|
||||||
|
{
|
||||||
|
private readonly AppDbContext _db;
|
||||||
|
public FacilitiesModel(AppDbContext db) => _db = db;
|
||||||
|
|
||||||
|
public List<Facility> Pending { get; private set; } = new();
|
||||||
|
public List<Facility> Verified { get; private set; } = new();
|
||||||
|
|
||||||
|
public async Task OnGetAsync() => await LoadAsync();
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnPostVerifyAsync(int id) => await SetVerified(id, true);
|
||||||
|
public async Task<IActionResult> OnPostUnverifyAsync(int id) => await SetVerified(id, false);
|
||||||
|
|
||||||
|
private async Task<IActionResult> SetVerified(int id, bool value)
|
||||||
|
{
|
||||||
|
var f = await _db.Facilities.FindAsync(id);
|
||||||
|
if (f is null) return NotFound();
|
||||||
|
f.IsVerified = value;
|
||||||
|
await _db.SaveChangesAsync();
|
||||||
|
return RedirectToPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task LoadAsync()
|
||||||
|
{
|
||||||
|
var all = await _db.Facilities
|
||||||
|
.Include(f => f.City).Include(f => f.District).Include(f => f.OwnerUser)
|
||||||
|
.OrderBy(f => f.Name).ToListAsync();
|
||||||
|
Pending = all.Where(f => !f.IsVerified).ToList();
|
||||||
|
Verified = all.Where(f => f.IsVerified).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
<p class="muted">
|
<p class="muted">
|
||||||
آگهیهای جمعآوریشده از کانالها را اینجا بررسی، ساختارمند و منتشر کن.
|
آگهیهای جمعآوریشده از کانالها را اینجا بررسی، ساختارمند و منتشر کن.
|
||||||
(@JalaliDate.ToPersianDigits(Model.Queue.Count.ToString()) در انتظار بررسی)
|
(@JalaliDate.ToPersianDigits(Model.Queue.Count.ToString()) در انتظار بررسی)
|
||||||
|
· <a asp-page="/Admin/Facilities">تأیید مراکز درمانی</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user