From 797bfef9641d137d64aba4549dd1574cdf8e64b1 Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Wed, 29 Apr 2026 00:35:27 +0330 Subject: [PATCH 1/2] fix(commission/dashboard): adjust week selector anchor and transform origins for better alignment --- src/BackOffice/Pages/Commission/Dashboard.razor | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/BackOffice/Pages/Commission/Dashboard.razor b/src/BackOffice/Pages/Commission/Dashboard.razor index 74096d2..4af9e73 100644 --- a/src/BackOffice/Pages/Commission/Dashboard.razor +++ b/src/BackOffice/Pages/Commission/Dashboard.razor @@ -89,7 +89,8 @@ Label="شماره هفته" Variant="Variant.Outlined" Margin="Margin.Dense" - AnchorOrigin="Origin.BottomCenter" + AnchorOrigin="Origin.BottomLeft" + TransformOrigin="Origin.TopLeft" Style="min-width: 400px;" ValueChanged="OnWeekChanged"> From 7fb2062721f3a7f9e269b52a0ca8d3a777f003d5 Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Fri, 1 May 2026 00:06:53 +0330 Subject: [PATCH 2/2] feat(dashboard): enhance dashboard layout and loading indicators, update week selector and package display feat(network): add activation type and package name display in network tree viewer style(admin-org-chart): refine styles for node cards and add new activation/renewal badges fix(admin-org-chart): adjust node dimensions for better visibility and add tooltip enhancements --- src/BackOffice/BackOffice.csproj | 2 +- .../Pages/Commission/Dashboard.razor | 467 ++++++++++-------- .../Pages/Network/NetworkTreeViewer.razor | 40 +- .../wwwroot/css/admin-org-chart.css | 51 +- src/BackOffice/wwwroot/js/admin-org-chart.js | 30 +- 5 files changed, 366 insertions(+), 224 deletions(-) diff --git a/src/BackOffice/BackOffice.csproj b/src/BackOffice/BackOffice.csproj index 1eb7033..1c7b056 100644 --- a/src/BackOffice/BackOffice.csproj +++ b/src/BackOffice/BackOffice.csproj @@ -138,7 +138,7 @@ - + diff --git a/src/BackOffice/Pages/Commission/Dashboard.razor b/src/BackOffice/Pages/Commission/Dashboard.razor index 4af9e73..35b043d 100644 --- a/src/BackOffice/Pages/Commission/Dashboard.razor +++ b/src/BackOffice/Pages/Commission/Dashboard.razor @@ -5,152 +5,89 @@ @using MudBlazor @using BackOffice.Pages.AutoComplete -
- داشبورد کمیسیون + - @* ── G11: راهنمای کمیسیون (Q28) ── *@ - - هر پکیج Pool پورسانت مستقل دارد. مبالغ ActivationFee به Pool پکیج مربوطه واریز می‌شود. - + @* ── عنوان صفحه ── *@ +
+ داشبورد کمیسیون + + مبلغ پورسانت هر هفته بین اعضاء تقسیم می‌شود. هر پکیج استخر مستقل دارد. + +
- @if (_isLoading) - { - - } - else - { - - - - - - استخر هفتگی - @(_poolData?.TotalPoolAmount.ToString("N0") ?? "0") تومان - @_currentWeekDisplayText - - - - - - - - تعداد تعادلها - @(_poolData?.TotalBalances.ToString("N0") ?? "0") - مجموع تعادل های فعال - - - - - - - - ارزش هر تعادل - @(_poolData?.ValuePerBalance.ToString("N0") ?? "0") تومان - قیمت واحد تعادل - - - - - - - - - وضعیت محاسبه - - - @(_poolData?.IsCalculated == true ? "محاسبه شده ✓" : "محاسبه نشده ✗") - - - @if (_poolData?.CalculatedAt != null) - { - var calculatedDate = _poolData.CalculatedAt.ToDateTime().ToLocalTime(); - var persianDate = PersianDateTime.ConvertToPersianDateTime(calculatedDate); - @($"در تاریخ {persianDate}") - } - else - { - @("در انتظار محاسبه") - } - - - - - - - - - - انتخاب هفته: - + @* ── فیلتر (اول از همه) ── *@ + + + @if (_allWeeks.Any()) { - - + + @if (_availableWeeks?.CurrentWeek != null) { - - - @_availableWeeks.CurrentWeek.DisplayText - + + + @_availableWeeks.CurrentWeek.DisplayText + جاری + } - + @if (_availableWeeks?.CalculatedWeeks?.Any() == true) { - هفته‌های محاسبه شده + تسویه‌شده @foreach (var week in _availableWeeks.CalculatedWeeks) { - - - @week.DisplayText + + + @week.DisplayText @if (week.TotalPoolAmount > 0) { - - @week.TotalPoolAmount.ToString("N0") تومان - + (@week.TotalPoolAmount.ToString("N0") T) } - + } } - + @if (_availableWeeks?.PendingWeeks?.Any() == true) { - هفته‌های محاسبه نشده + در انتظار تسویه @foreach (var week in _availableWeeks.PendingWeeks) { - - - @week.DisplayText - + + + @week.DisplayText + } } - + @if (_availableWeeks?.FutureWeeks?.Any() == true) { هفته‌های آینده @foreach (var week in _availableWeeks.FutureWeeks) { - - - @week.DisplayText - + + + @week.DisplayText + } } @@ -160,114 +97,222 @@ { لیست هفته‌ها بارگذاری نشده } + + - - - بارگذاری - -
- + - - @if (_poolData != null) - { - - جزئیات استخر - - - - شناسه استخر: - @_poolData.Id - - - پکیج: - - @if (!string.IsNullOrEmpty(_poolData.PackageTitle)) - { - @_poolData.PackageTitle - } - else - { - - - } - - - - شماره هفته: - @_currentWeekDisplayName - - - مجموع استخر: - @_poolData.TotalPoolAmount.ToString("N0") تومان - - - تعداد تعادل: - @_poolData.TotalBalances - - - ارزش هر تعادل: - @_poolData.ValuePerBalance.ToString("N0") تومان - - - وضعیت: - - - @(_poolData.IsCalculated ? "محاسبه شده" : "محاسبه نشده") - - - - - تاریخ محاسبه: - - @if (_poolData.CalculatedAt != null) - { - @_poolData.CalculatedAt.ToDateTime().ToLocalTime().MiladiToJalaliWithTime() - } - else - { - - - } - - - - تاریخ ایجاد: - @_poolData.Created.ToDateTime().ToLocalTime().MiladiToJalaliWithTime() - - - - - } + + + نمایش + + + + - - - عملیات سریع - - - مشاهده پرداخت‌ها - - - درخواست‌های برداشت - - - اجرای محاسبه دستی - + @* ── لودینگ ── *@ + @if (_isLoading) + { + + + + در حال بارگذاری اطلاعات استخر… } -
+ else + { + @* ── نوار وضعیت هفته / پکیج ── *@ + + + + @_currentWeekDisplayText + + @if (!string.IsNullOrEmpty(_poolData?.PackageTitle)) + { + + + @_poolData.PackageTitle + + } + + + + @if (_poolData != null && _poolData.Id > 0) + { + @if (_poolData.IsCalculated) + { + + تسویه انجام شده + + } + else + { + + در انتظار تسویه + + } + } + + + + @* ── ۳ کارت اصلی ── *@ + + @* کارت ۱: کل مبلغ استخر *@ + + + + + + کل مبلغ استخر پورسانت + + + @((_poolData?.TotalPoolAmount ?? 0).ToString("N0")) + + تومان — جمع کارمزد فعال‌سازی‌های این هفته + + + + + @* کارت ۲: تعداد واحدهای پورسانت *@ + + + + + + واحدهای پورسانت (بالانس) + + + + + + @((_poolData?.TotalBalances ?? 0).ToString("N0")) + + واحد — مجموع همه اعضاء فعال + + + + + @* کارت ۳: سهم هر واحد *@ + + + + + + سهم پورسانت هر واحد + + + @((_poolData?.ValuePerBalance ?? 0).ToString("N0")) + + + تومان — @((_poolData?.IsCalculated == true) ? "قطعی شده" : "قطعی نشده") + + + + + + + @* ── اعتبارسنجی مبلغ استخر ── *@ + @if (_poolData != null && _poolData.Id > 0) + { + @if (!_poolData.ValidationIsValid) + { + + مبلغ استخر با تعداد فعال‌سازی‌های دیتابیس مطابقت ندارد + + + مبلغ ثبت‌شده + @_poolData.TotalPoolAmount.ToString("N0") تومان + + + مبلغ انتظاری (@_poolData.ValidationActivationCount فعال‌سازی) + @_poolData.ValidationExpectedAmount.ToString("N0") تومان + + + اختلاف + + @_poolData.ValidationDiscrepancy.ToString("N0") تومان + + + + + } + else if (_poolData.ValidationActivationCount > 0) + { + + مبلغ استخر صحیح است — با @_poolData.ValidationActivationCount فعال‌سازی در این هفته مطابقت دارد. + + } + } + + @* ── جزئیات تکمیلی (بدون تکرار اطلاعات کارت‌ها) ── *@ + @if (_poolData != null && _poolData.Id > 0) + { + + + + + + شناسه استخر + #@_poolData.Id + + + تاریخ ایجاد استخر + @_poolData.Created.ToDateTime().ToLocalTime().MiladiToJalaliWithTime() + + @if (_poolData.CalculatedAt != null) + { + + تاریخ تسویه + @_poolData.CalculatedAt.ToDateTime().ToLocalTime().MiladiToJalaliWithTime() + + } + + + + + } + + @* ── دکمه‌های عملیاتی ── *@ + + + + پرداخت‌های این هفته + + + درخواست‌های برداشت + + + @if (_poolData?.IsCalculated != true) + { + + اجرای تسویه دستی + + } + + + } + + diff --git a/src/BackOffice/Pages/Network/NetworkTreeViewer.razor b/src/BackOffice/Pages/Network/NetworkTreeViewer.razor index 860cc13..ab841f7 100644 --- a/src/BackOffice/Pages/Network/NetworkTreeViewer.razor +++ b/src/BackOffice/Pages/Network/NetworkTreeViewer.razor @@ -169,6 +169,42 @@ + + + @if (context.Item.IsNewActivation == null) + { + - + } + else if (context.Item.IsNewActivation == true) + { + + عضو جدید + + } + else + { + + خرید مجدد + + } + + + + + + @if (!string.IsNullOrEmpty(context.Item.PackageName)) + { + + @context.Item.PackageName + + } + else + { + - + } + + + @@ -337,7 +373,9 @@ isClubActive = n.IsClubActive, isActivatedInTargetWeek = n.IsActivatedInTargetWeek, activationWeekDefinitionId = n.ActivationWeekDefinitionId, - clubActivatedAt = n.ClubActivatedAt?.ToDateTime().ToLocalTime().MiladiToJalali() ?? "" + clubActivatedAt = n.ClubActivatedAt?.ToDateTime().ToLocalTime().MiladiToJalali() ?? "", + isNewActivation = n.IsNewActivation, + packageName = n.PackageName ?? "" }).ToArray(); var options = new { filterWeek = _activationWeekFilter }; diff --git a/src/BackOffice/wwwroot/css/admin-org-chart.css b/src/BackOffice/wwwroot/css/admin-org-chart.css index c1c55fa..fe08397 100644 --- a/src/BackOffice/wwwroot/css/admin-org-chart.css +++ b/src/BackOffice/wwwroot/css/admin-org-chart.css @@ -94,8 +94,9 @@ .admin-node-card .node-meta { display: flex; align-items: center; - gap: 6px; - margin-top: 2px; + gap: 4px; + margin-top: 3px; + flex-wrap: wrap; } .admin-node-card .level-badge { @@ -124,8 +125,8 @@ display: flex; justify-content: space-between; align-items: center; - margin-top: 6px; - padding-top: 6px; + margin-top: 5px; + padding-top: 5px; border-top: 1px solid #f0f0f0; font-size: 10px; } @@ -204,6 +205,48 @@ animation: pulse-highlight 1.5s ease-in-out infinite; } +/* نوع فعالسازی - inline pill */ +.admin-node-card .activation-pill { + display: inline-flex; + align-items: center; + padding: 1px 6px; + border-radius: 8px; + font-size: 9px; + font-weight: 600; + white-space: nowrap; + line-height: 1.4; +} + +.admin-node-card .new-member-pill { + background: #e8f5e9; + color: #2e7d32; + border: 1px solid #a5d6a7; +} + +.admin-node-card .renewal-pill { + background: #ede7f6; + color: #5e35b1; + border: 1px solid #b39ddb; +} + +/* نام پکیج badge */ +.admin-node-card .package-name-badge { + display: inline-flex; + align-items: center; + height: 14px; + padding: 0 6px; + margin-top: 2px; + border-radius: 7px; + font-size: 9px; + color: #546e7a; + background: #eceff1; + border: 1px solid #b0bec5; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: 120px; +} + @keyframes pulse-highlight { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.2); opacity: 0.8; } diff --git a/src/BackOffice/wwwroot/js/admin-org-chart.js b/src/BackOffice/wwwroot/js/admin-org-chart.js index 61c82e7..a78b038 100644 --- a/src/BackOffice/wwwroot/js/admin-org-chart.js +++ b/src/BackOffice/wwwroot/js/admin-org-chart.js @@ -39,8 +39,8 @@ window.AdminOrgChart = { this.chart = new d3.OrgChart() .container('#' + containerId) .data(data) - .nodeWidth((d) => 160) - .nodeHeight((d) => 80) + .nodeWidth((d) => 178) + .nodeHeight((d) => 92) .childrenMargin((d) => 60) .compactMarginBetween((d) => 20) .compactMarginPair((d) => 20) @@ -83,12 +83,19 @@ window.AdminOrgChart = { `; } - // Highlight badge for target week matches - let highlightBadge = ''; - if (weekFilterActive && isTargetWeek) { - highlightBadge = '
'; + // نوع فعالسازی - inline pill در meta row + let activationTypePill = ''; + if (data.isNewActivation === true) { + activationTypePill = 'عضو جدید'; + } else if (data.isNewActivation === false) { + activationTypePill = 'تمدید'; } + // نام پکیج badge + const packageBadge = data.packageName + ? `
${data.packageName}
` + : ''; + // Avatar - first letter of name const firstChar = data.userName ? data.userName.charAt(0).toUpperCase() : '?'; @@ -114,6 +121,14 @@ window.AdminOrgChart = { if (data.activationWeekDefinitionId) { tooltipLines.push(`📆 هفته: ${data.activationWeekDefinitionId}`); } + if (data.packageName) { + tooltipLines.push(`📦 پکیج: ${data.packageName}`); + } + if (data.isNewActivation === true) { + tooltipLines.push('🆕 نوع: اولین فعال‌سازی'); + } else if (data.isNewActivation === false) { + tooltipLines.push('🔄 نوع: خرید مجدد'); + } if (weekFilterActive) { tooltipLines.push(isTargetWeek ? '🎯 فعال در هفته انتخابی' : '⚪ خارج از هفته انتخابی'); } @@ -125,14 +140,15 @@ window.AdminOrgChart = { data-user-id="${data.userId}" title="${tooltipText}"> ${weekIndicator} - ${highlightBadge}
${firstChar}
${data.userName || 'کاربر ' + data.userId}
+ ${packageBadge}
${levelBadge} ${legText ? `${legText}` : ''} + ${activationTypePill}