Redesign header menu: separate account dropdown from dashboard nav
The profile dropdown was doing three jobs at once (account actions, the job-seeker panel menu, and the admin panel menu) and a stray inline @if for the notification badge leaked into the markup as literal text. - Profile dropdown is now account-only: identity card (avatar + name + phone), one role-aware dashboard entry, edit profile, logout. This removes the leaked @if and de-clutters the menu. - Dashboard menu is centralized in _PanelNav and auto-rendered by the layout on every logged-in panel page (/Admin, /Me, /Employer, /Preferences) instead of being duplicated in the dropdown and pages. - Drop the now-duplicate manual <partial name="_PanelNav" /> from Overview, Ingested, Me/Index, Employer/Index. - CSS: identity-card (.pd-id) styles + mobile tweaks. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -6,20 +6,26 @@
|
||||
var title = ViewData["Title"] as string;
|
||||
int unreadCount = 0;
|
||||
int meId = 0;
|
||||
string? meName = null;
|
||||
string? meFullName = null;
|
||||
string? mePhone = null;
|
||||
bool meHasAvatar = false;
|
||||
if (User.Identity?.IsAuthenticated == true && int.TryParse(User.FindFirstValue(ClaimTypes.NameIdentifier), out meId))
|
||||
{
|
||||
unreadCount = await Notifications.UnreadCountAsync(meId);
|
||||
var info = await Db.Users.Where(u => u.Id == meId)
|
||||
.Select(u => new { u.FullName, u.Phone, HasAvatar = u.Avatar != null }).FirstOrDefaultAsync();
|
||||
meName = string.IsNullOrWhiteSpace(info?.FullName) ? info?.Phone : info!.FullName;
|
||||
meFullName = string.IsNullOrWhiteSpace(info?.FullName) ? null : info!.FullName!.Trim();
|
||||
mePhone = info?.Phone;
|
||||
meHasAvatar = info?.HasAvatar ?? false;
|
||||
}
|
||||
// Person glyph when there's no real name yet (avoid showing a phone digit like "0").
|
||||
var meInitial = (!string.IsNullOrWhiteSpace(meName) && !char.IsDigit(meName!.Trim()[0]))
|
||||
? meName!.Trim().Substring(0, 1) : "👤";
|
||||
var meLabel = (!string.IsNullOrWhiteSpace(meName) && !char.IsDigit(meName!.Trim()[0])) ? meName! : "حساب من";
|
||||
// Avatar glyph/label: prefer a real name; never show a bare phone digit like "0".
|
||||
var meInitial = meFullName is not null ? meFullName.Substring(0, 1) : "👤";
|
||||
var meLabel = meFullName ?? "حساب من";
|
||||
|
||||
// Single, role-aware dashboard entry — the full menu lives in the panel sub-nav (_PanelNav).
|
||||
var dashUrl = "/Me/Index"; var dashLabel = "داشبورد من"; var dashIcon = "🗂️";
|
||||
if (User.IsInRole("Admin")) { dashUrl = "/Admin/Overview"; dashLabel = "پنل مدیریت"; dashIcon = "🛠️"; }
|
||||
else if (User.IsInRole("FacilityAdmin")) { dashUrl = "/Employer/Index"; dashLabel = "پنل کارفرما"; dashIcon = "🏥"; }
|
||||
|
||||
// --- SEO context ---
|
||||
var baseUrl = $"{Context.Request.Scheme}://{Context.Request.Host}";
|
||||
@@ -33,6 +39,11 @@
|
||||
string[] noindexPrefixes = { "/Admin", "/Me", "/Employer", "/Account", "/Preferences" };
|
||||
var noIndex = (ViewData["NoIndex"] as bool? ?? false)
|
||||
|| noindexPrefixes.Any(p => path.StartsWith(p, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
// Show the centralized dashboard sub-nav on any logged-in panel page.
|
||||
string[] panelPrefixes = { "/Admin", "/Me", "/Employer", "/Preferences" };
|
||||
var showPanelNav = User.Identity?.IsAuthenticated == true
|
||||
&& panelPrefixes.Any(p => path.StartsWith(p, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
<!DOCTYPE html>
|
||||
<html lang="fa" dir="rtl">
|
||||
@@ -126,22 +137,26 @@
|
||||
<span class="avatar-caret">▾</span>
|
||||
</label>
|
||||
<nav class="profile-dropdown">
|
||||
<div class="pd-head">@meName</div>
|
||||
<div class="pd-id">
|
||||
@if (meHasAvatar)
|
||||
{
|
||||
<img class="avatar-img" src="/avatar/@meId" alt="" />
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="avatar-fallback">@meInitial</span>
|
||||
}
|
||||
<div class="pd-id-text">
|
||||
<strong>@(meFullName ?? "کاربر همکادر")</strong>
|
||||
@if (mePhone is not null)
|
||||
{
|
||||
<span class="muted" dir="ltr">@mePhone</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="pd-sep"></div>
|
||||
<a href="@dashUrl" data-tour="panel">@dashIcon @dashLabel</a>
|
||||
<a asp-page="/Me/Profile">👤 ویرایش پروفایل</a>
|
||||
<a asp-page="/Me/Index" data-tour="panel">🗂️ پنل کارجو</a>
|
||||
<a asp-page="/Me/Alerts">🔎 هشدارهای شغلی</a>
|
||||
<a asp-page="/Preferences/Index">⭐ علاقهمندیها</a>
|
||||
<a asp-page="/Me/Notifications">🔔 اعلانها@if (unreadCount > 0) {<span class="bell-badge" style="position:static; margin-inline-start:6px;">@JalaliDate.ToPersianDigits(unreadCount > 99 ? "99+" : unreadCount.ToString())</span>}</a>
|
||||
@if (User.IsInRole("FacilityAdmin"))
|
||||
{
|
||||
<a asp-page="/Employer/Index">🏥 پنل کارفرما</a>
|
||||
}
|
||||
@if (User.IsInRole("Admin"))
|
||||
{
|
||||
<div class="pd-sep"></div>
|
||||
<a asp-page="/Admin/Overview">🛠️ پنل مدیریت</a>
|
||||
<a asp-page="/Admin/Settings">⚙️ تنظیمات</a>
|
||||
}
|
||||
<div class="pd-sep"></div>
|
||||
<form method="post" asp-page="/Account/Logout">
|
||||
<button type="submit" class="pd-logout">🚪 خروج</button>
|
||||
@@ -159,6 +174,10 @@
|
||||
</header>
|
||||
|
||||
<main role="main">
|
||||
@if (showPanelNav)
|
||||
{
|
||||
<partial name="_PanelNav" />
|
||||
}
|
||||
@RenderBody()
|
||||
</main>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user