eae38373b9
- /Admin/Overview: platform monitoring stats (users by role, facilities, listings, applies, push subs, queue, reports, bans) - /Admin/Users: search/filter + ban/unban (User.IsBanned + reason); banned users blocked at login - /Admin/Broadcast: send announcement (in-app + web push) to all / staff / employers via NotificationService - Reports: report button on shift/job detail → /report endpoint → /Admin/Reports (resolve/dismiss) - Settings: 'send test SMS' button; admin cross-nav links; SMS API config already in place - migration AdminBanReports; verified overview/users/broadcast/report persist Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
70 lines
3.7 KiB
Plaintext
70 lines
3.7 KiB
Plaintext
@page
|
|
@model JobsMedical.Web.Pages.Admin.UsersModel
|
|
@{
|
|
ViewData["Title"] = "مدیریت کاربران";
|
|
string RoleLabel(UserRole r) => r switch { UserRole.Admin => "مدیر", UserRole.FacilityAdmin => "کارفرما", _ => "کادر درمان" };
|
|
}
|
|
|
|
<div class="page-head">
|
|
<div class="container">
|
|
<h1>مدیریت کاربران</h1>
|
|
<p class="muted">
|
|
<a asp-page="/Admin/Index">صف آگهیها</a> ·
|
|
<a asp-page="/Admin/Overview">داشبورد</a> ·
|
|
<a asp-page="/Admin/Reports">گزارشها</a> ·
|
|
<a asp-page="/Admin/Broadcast">ارسال اعلان</a>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="container section">
|
|
@if (TempData["err"] is string e) { <div class="alert" style="background:#fdeaea; color:var(--danger);">@e</div> }
|
|
|
|
<form method="get" class="card card-pad" style="display:flex; gap:8px; align-items:end; flex-wrap:wrap; margin-bottom:14px;">
|
|
<div class="filter-group" style="margin:0; flex:1; min-width:160px;">
|
|
<label>جستجو (شماره/نام)</label>
|
|
<input type="text" name="Q" value="@Model.Q" dir="ltr" />
|
|
</div>
|
|
<div class="filter-group" style="margin:0;">
|
|
<label>نقش</label>
|
|
<select name="RoleFilter">
|
|
<option value="">همه</option>
|
|
<option value="0" selected="@(Model.RoleFilter == UserRole.Doctor)">کادر درمان</option>
|
|
<option value="2" selected="@(Model.RoleFilter == UserRole.FacilityAdmin)">کارفرما</option>
|
|
<option value="1" selected="@(Model.RoleFilter == UserRole.Admin)">مدیر</option>
|
|
</select>
|
|
</div>
|
|
<button type="submit" class="btn btn-outline">فیلتر</button>
|
|
</form>
|
|
|
|
@foreach (var row in Model.Users)
|
|
{
|
|
var u = row.User;
|
|
<div class="card card-pad" style="margin-bottom:10px; display:flex; justify-content:space-between; align-items:center; gap:10px; flex-wrap:wrap;">
|
|
<div>
|
|
<strong dir="ltr">@JalaliDate.ToPersianDigits(u.Phone)</strong>
|
|
@if (!string.IsNullOrEmpty(u.FullName)) { <text> — @u.FullName</text> }
|
|
<span class="badge badge-type">@RoleLabel(u.Role)</span>
|
|
@if (row.Facilities > 0) { <span class="badge badge-job">@JalaliDate.ToPersianDigits(row.Facilities.ToString()) مرکز</span> }
|
|
@if (u.IsBanned) { <span class="badge" style="background:#fdeaea;color:var(--danger);">مسدود</span> }
|
|
<div class="muted" style="font-size:12px;">عضویت: @JalaliDate.ToLongDate(DateOnly.FromDateTime(u.CreatedAt))@(u.IsBanned && u.BanReason != null ? " — دلیل مسدودی: " + u.BanReason : "")</div>
|
|
</div>
|
|
@if (u.Role != UserRole.Admin)
|
|
{
|
|
@if (u.IsBanned)
|
|
{
|
|
<form method="post"><button asp-page-handler="Unban" asp-route-id="@u.Id" class="btn btn-outline">رفع مسدودی</button></form>
|
|
}
|
|
else
|
|
{
|
|
<form method="post" style="display:flex; gap:6px;" onsubmit="return confirm('این کاربر مسدود شود؟');">
|
|
<input type="text" name="reason" placeholder="دلیل (اختیاری)" style="width:150px;" />
|
|
<button asp-page-handler="Ban" asp-route-id="@u.Id" class="btn btn-outline" style="color:var(--danger); border-color:var(--danger);">مسدود کردن</button>
|
|
</form>
|
|
}
|
|
}
|
|
</div>
|
|
}
|
|
@if (Model.Users.Count == 0) { <div class="card empty-state">کاربری یافت نشد.</div> }
|
|
</div>
|