From c243b59113444c423cf0d1316053eb8bcdd85a1e Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Tue, 25 Aug 2026 21:40:38 +0330 Subject: [PATCH 1/6] feat(address): enhance address management in checkout and summary components - Updated the Checkout and CheckoutSummary components to allow users to add new addresses directly from the interface, improving accessibility and user experience. - Introduced dialog functionality for adding and editing addresses, streamlining the address management process. - Removed the calculation of order PV from the OrderDetail component, simplifying the order details view and improving performance. These changes enhance the usability of the checkout process by making address management more intuitive and efficient. --- docs/CUSTOMER-SERVICES.md | 1 - .../Pages/DiscountStore/Checkout.razor | 26 +++++++++++++----- .../Pages/DiscountStore/Checkout.razor.cs | 27 +++++++++++++++++++ .../Pages/Store/CheckoutSummary.razor | 26 +++++++++++++----- .../Pages/Store/CheckoutSummary.razor.cs | 27 +++++++++++++++++++ .../Pages/Store/OrderDetail.razor | 24 ----------------- .../Pages/Store/OrderDetail.razor.cs | 6 ----- .../Utilities/OrderService.cs | 18 ------------- 8 files changed, 94 insertions(+), 61 deletions(-) diff --git a/docs/CUSTOMER-SERVICES.md b/docs/CUSTOMER-SERVICES.md index 05ff8bd..41a173e 100644 --- a/docs/CUSTOMER-SERVICES.md +++ b/docs/CUSTOMER-SERVICES.md @@ -101,7 +101,6 @@ | 6.6 | `UserOrderContract.SubmitShopBuyOrder` | `UserOrderContract` | `/checkout-summary` | ثبت سفارش و پرداخت از کیف پول | | 6.7 | `OrderService.GetOrdersAsync` | `UserOrderContract.GetCustomerOrders` | `/orders` | لیست سفارش‌های کاربر | | 6.8 | `OrderService.GetOrderAsync` | `UserOrderContract.GetCustomerOrder` | `/order/{id}`, `/order-tracking/{id}` | جزئیات یک سفارش | -| 6.9 | `OrderService.CalculateOrderPVAsync` | `UserOrderContract.CalculateOrderPV` | `/order/{id}` | محاسبه PV سفارش | | 6.10 | `VATService.GetRateAsync` | `UserOrderContract` (via scope) | Store/Discount صفحات قیمت | نرخ مالیات بر ارزش افزوده (کش روزانه) | | 6.11 | `WalletService.GetBalancesAsync` | `UserWalletContract` | `/checkout-summary` | بررسی موجودی برای پرداخت سفارش | diff --git a/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor b/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor index beba9e2..c455966 100644 --- a/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor +++ b/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor @@ -22,9 +22,11 @@ else if (_addresses.Count == 0) { - هیچ آدرسی ثبت نشده است. لطفاً از بخش پروفایل آدرس خود را اضافه کنید. + هیچ آدرسی ثبت نشده است. می‌توانید همین‌جا آدرس جدید اضافه کنید. - افزودن آدرس + افزودن آدرس } else { @@ -41,13 +43,25 @@ @address.Title @address.Address - @if (address.IsDefault) - { - پیش‌فرض - } + + @if (address.IsDefault) + { + پیش‌فرض + } + + + + } + افزودن آدرس جدید } diff --git a/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor.cs b/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor.cs index 1185e0b..3068fb4 100644 --- a/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor.cs +++ b/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Components; using CMSMicroservice.Protobuf.Protos.UserAddress; +using FrontOffice.Main.Pages.Profile.Components; using FrontOffice.Main.Utilities; using MudBlazor; @@ -61,12 +62,14 @@ public partial class Checkout else { _addresses = new(); + _selectedAddress = null; } } catch (Exception ex) { Snackbar.Add($"خطا در بارگذاری آدرس‌ها: {ex.Message}", Severity.Error); _addresses = new(); + _selectedAddress = null; } finally { @@ -75,6 +78,30 @@ public partial class Checkout } } + private async Task OpenAddAddressDialog() + { + var dialog = await DialogService.ShowAsync("افزودن آدرس جدید"); + var result = await dialog.Result; + if (result is { Canceled: false }) + { + await AuthService.RefreshTokenAsync(); + await LoadAddresses(); + } + } + + private async Task OpenEditAddressDialog(CustomerAddressModel address) + { + var dialog = await DialogService.ShowAsync("ویرایش آدرس", new DialogParameters + { + { x => x.Model, address } + }); + var result = await dialog.Result; + if (result is { Canceled: false }) + { + await LoadAddresses(); + } + } + private async Task PlaceOrder() { if (!CanPlaceOrder || _selectedAddress is null) diff --git a/src/FrontOffice.Main/Pages/Store/CheckoutSummary.razor b/src/FrontOffice.Main/Pages/Store/CheckoutSummary.razor index b894fb3..9fcf078 100644 --- a/src/FrontOffice.Main/Pages/Store/CheckoutSummary.razor +++ b/src/FrontOffice.Main/Pages/Store/CheckoutSummary.razor @@ -21,9 +21,11 @@ else if (_addresses.Count == 0) { - هیچ آدرسی ثبت نشده است. لطفاً از بخش پروفایل آدرس خود را اضافه کنید. + هیچ آدرسی ثبت نشده است. می‌توانید همین‌جا آدرس جدید اضافه کنید. - افزودن آدرس + افزودن آدرس } else { @@ -40,13 +42,25 @@ @address.Title @address.Address - @if (address.IsDefault) - { - پیش‌فرض - } + + @if (address.IsDefault) + { + پیش‌فرض + } + + + + } + افزودن آدرس جدید } diff --git a/src/FrontOffice.Main/Pages/Store/CheckoutSummary.razor.cs b/src/FrontOffice.Main/Pages/Store/CheckoutSummary.razor.cs index 0c8aedf..479c633 100644 --- a/src/FrontOffice.Main/Pages/Store/CheckoutSummary.razor.cs +++ b/src/FrontOffice.Main/Pages/Store/CheckoutSummary.razor.cs @@ -1,5 +1,6 @@ using CMSMicroservice.Protobuf.Protos.UserAddress; using CMSMicroservice.Protobuf.Protos.UserOrder; +using FrontOffice.Main.Pages.Profile.Components; using FrontOffice.Main.Shared; using FrontOffice.Main.Utilities; using Microsoft.AspNetCore.Components; @@ -72,12 +73,14 @@ public partial class CheckoutSummary : ComponentBase else { _addresses = new(); + _selectedAddress = null; } } catch (Exception ex) { Snackbar.Add($"خطا در بارگذاری آدرس‌ها: {ex.Message}", Severity.Error); _addresses = new(); + _selectedAddress = null; } finally { @@ -86,6 +89,30 @@ public partial class CheckoutSummary : ComponentBase } } + private async Task OpenAddAddressDialog() + { + var dialog = await DialogService.ShowAsync("افزودن آدرس جدید"); + var result = await dialog.Result; + if (result is { Canceled: false }) + { + await AuthService.RefreshTokenAsync(); + await LoadAddresses(); + } + } + + private async Task OpenEditAddressDialog(CustomerAddressModel address) + { + var dialog = await DialogService.ShowAsync("ویرایش آدرس", new DialogParameters + { + { x => x.Model, address } + }); + var result = await dialog.Result; + if (result is { Canceled: false }) + { + await LoadAddresses(); + } + } + private async Task PlaceOrder() { if (!CanPlaceOrder || _selectedAddress is null) diff --git a/src/FrontOffice.Main/Pages/Store/OrderDetail.razor b/src/FrontOffice.Main/Pages/Store/OrderDetail.razor index abfd053..d94751d 100644 --- a/src/FrontOffice.Main/Pages/Store/OrderDetail.razor +++ b/src/FrontOffice.Main/Pages/Store/OrderDetail.razor @@ -112,30 +112,6 @@ else } - - @* نمایش PV سفارش *@ - @if (_pvData != null && _pvData.TotalPv > 0) - { - - - - - امتیاز فروش (PV) - - @foreach (var product in _pvData.Products) - { - - @product.ProductTitle × @product.Quantity - @string.Format("{0:N0}", product.TotalPv) PV - - } - - - جمع PV: - @string.Format("{0:N0}", _pvData.TotalPv) PV - - - } diff --git a/src/FrontOffice.Main/Pages/Store/OrderDetail.razor.cs b/src/FrontOffice.Main/Pages/Store/OrderDetail.razor.cs index a8ed6fa..ec8abbf 100644 --- a/src/FrontOffice.Main/Pages/Store/OrderDetail.razor.cs +++ b/src/FrontOffice.Main/Pages/Store/OrderDetail.razor.cs @@ -12,17 +12,12 @@ public partial class OrderDetail : ComponentBase [Parameter] public long id { get; set; } private GetUserOrderResponse? _order; - private CalculateOrderPVResponse? _pvData; private bool _loading; protected override async Task OnParametersSetAsync() { _loading = true; _order = await OrderService.GetOrderAsync(id); - if (_order != null) - { - _pvData = await OrderService.CalculateOrderPVAsync(id); - } _loading = false; } @@ -52,4 +47,3 @@ public partial class OrderDetail : ComponentBase private static string GetProductImageUrl(string? imageUrl) => string.IsNullOrWhiteSpace(imageUrl) ? "/images/product-placeholder.svg" : imageUrl.TrimStart('/'); } - diff --git a/src/FrontOffice.Main/Utilities/OrderService.cs b/src/FrontOffice.Main/Utilities/OrderService.cs index 39d9cfb..5f3ca8f 100644 --- a/src/FrontOffice.Main/Utilities/OrderService.cs +++ b/src/FrontOffice.Main/Utilities/OrderService.cs @@ -97,22 +97,4 @@ public class OrderService return 0.10; } } - - /// - /// محاسبه PV سفارش - /// - public async Task CalculateOrderPVAsync(long orderId) - { - try - { - return await _userOrderContractClient.CalculateOrderPVAsync(new CalculateOrderPVRequest - { - OrderId = orderId - }); - } - catch - { - return null; - } - } } \ No newline at end of file From 307302e33d577bb09dc1fd29038db2defed81b9e Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Tue, 25 Aug 2026 22:39:30 +0330 Subject: [PATCH 2/6] feat(organization-chart): enhance organization chart with leg totals and styling improvements - Updated the organization chart to include gold and silver leg totals for better visibility of user metrics. - Modified the CSS for the chart to improve layout and styling, ensuring a more user-friendly interface. - Adjusted JavaScript to dynamically display leg scores, enhancing the overall interactivity of the chart. These changes improve the clarity and usability of the organization chart, providing users with essential metrics at a glance. --- src/FrontOffice.Main/FrontOffice.Main.csproj | 2 +- .../Components/OrganizationChart.razor.cs | 6 ++++- .../Utilities/NetworkMembershipDtos.cs | 23 ++++++++++++++++++- .../Utilities/NetworkMembershipService.cs | 4 ++++ .../wwwroot/css/org-chart.css | 20 ++++++++++++++-- src/FrontOffice.Main/wwwroot/js/org-chart.js | 15 ++++++++++-- 6 files changed, 63 insertions(+), 7 deletions(-) diff --git a/src/FrontOffice.Main/FrontOffice.Main.csproj b/src/FrontOffice.Main/FrontOffice.Main.csproj index f7089c0..b2ac49b 100644 --- a/src/FrontOffice.Main/FrontOffice.Main.csproj +++ b/src/FrontOffice.Main/FrontOffice.Main.csproj @@ -11,7 +11,7 @@ - + diff --git a/src/FrontOffice.Main/Pages/Profile/Components/OrganizationChart.razor.cs b/src/FrontOffice.Main/Pages/Profile/Components/OrganizationChart.razor.cs index 4f6ac05..87e6719 100644 --- a/src/FrontOffice.Main/Pages/Profile/Components/OrganizationChart.razor.cs +++ b/src/FrontOffice.Main/Pages/Profile/Components/OrganizationChart.razor.cs @@ -110,7 +110,11 @@ public partial class OrganizationChart : IAsyncDisposable activationWeekNumber = n.ActivationWeekNumber, joinedAt = n.JoinedAt, referralCode = n.ReferralCode, - packageName = n.PackageName ?? string.Empty + packageName = n.PackageName ?? string.Empty, + goldLeftLegTotal = n.GoldLeftLegTotal, + goldRightLegTotal = n.GoldRightLegTotal, + silverLeftLegTotal = n.SilverLeftLegTotal, + silverRightLegTotal = n.SilverRightLegTotal }).ToArray(); await JSRuntime.InvokeVoidAsync("OrgChart.init", "org-chart-container", flatData, _dotNetHelper); diff --git a/src/FrontOffice.Main/Utilities/NetworkMembershipDtos.cs b/src/FrontOffice.Main/Utilities/NetworkMembershipDtos.cs index 8bbdb37..25a0664 100644 --- a/src/FrontOffice.Main/Utilities/NetworkMembershipDtos.cs +++ b/src/FrontOffice.Main/Utilities/NetworkMembershipDtos.cs @@ -26,6 +26,18 @@ public class NetworkNodeDto /// نام پکیج موثر (مثلاً پکیج طلایی / نقره‌ای) /// public string? PackageName { get; set; } + + /// آخرین امتیاز پای چپ پکیج طلایی + public int GoldLeftLegTotal { get; set; } + + /// آخرین امتیاز پای راست پکیج طلایی + public int GoldRightLegTotal { get; set; } + + /// آخرین امتیاز پای چپ پکیج نقره‌ای + public int SilverLeftLegTotal { get; set; } + + /// آخرین امتیاز پای راست پکیج نقره‌ای + public int SilverRightLegTotal { get; set; } } /// @@ -53,6 +65,11 @@ public class FlatNetworkNodeDto /// نام پکیج موثر (مثلاً پکیج طلایی / نقره‌ای) /// public string? PackageName { get; set; } + + public int GoldLeftLegTotal { get; set; } + public int GoldRightLegTotal { get; set; } + public int SilverLeftLegTotal { get; set; } + public int SilverRightLegTotal { get; set; } } /// @@ -92,7 +109,11 @@ public class NetworkTreeDto ActivationWeekNumber = node.ActivationWeekNumber, JoinedAt = node.JoinedAt, ReferralCode = node.ReferralCode, - PackageName = node.PackageName + PackageName = node.PackageName, + GoldLeftLegTotal = node.GoldLeftLegTotal, + GoldRightLegTotal = node.GoldRightLegTotal, + SilverLeftLegTotal = node.SilverLeftLegTotal, + SilverRightLegTotal = node.SilverRightLegTotal }; result.Add(flatNode); diff --git a/src/FrontOffice.Main/Utilities/NetworkMembershipService.cs b/src/FrontOffice.Main/Utilities/NetworkMembershipService.cs index 4983855..6bfa218 100644 --- a/src/FrontOffice.Main/Utilities/NetworkMembershipService.cs +++ b/src/FrontOffice.Main/Utilities/NetworkMembershipService.cs @@ -138,6 +138,10 @@ public class NetworkMembershipService IsClubActive = node.IsClubActive, ReferralCode = node.ReferralCode, PackageName = string.IsNullOrWhiteSpace(node.PackageName) ? null : node.PackageName, + GoldLeftLegTotal = node.GoldLeftLegTotal, + GoldRightLegTotal = node.GoldRightLegTotal, + SilverLeftLegTotal = node.SilverLeftLegTotal, + SilverRightLegTotal = node.SilverRightLegTotal, ActivationWeekNumber = node.ActivationWeekDefinitionId?.ToString(), JoinedAt = node.JoinedAt?.ToDateTime(), LeftChild = MapNodeFromProto(node.LeftChild), diff --git a/src/FrontOffice.Main/wwwroot/css/org-chart.css b/src/FrontOffice.Main/wwwroot/css/org-chart.css index 4ac39ab..b80b895 100644 --- a/src/FrontOffice.Main/wwwroot/css/org-chart.css +++ b/src/FrontOffice.Main/wwwroot/css/org-chart.css @@ -72,10 +72,10 @@ /* Compact Header */ .node-header-compact { display: flex; - align-items: center; + align-items: flex-start; gap: 6px; padding: 6px 8px; - height: 100%; + min-height: 100%; background: linear-gradient(135deg, #f8f9fa 0%, #fff 100%); } @@ -141,6 +141,22 @@ max-width: 120px; } +/* D3: طلایی / نقره‌ای — پای چپ و راست */ +.node-leg-scores { + margin-top: 3px; + line-height: 1.25; + font-size: 8px; + font-weight: 600; +} + +.node-leg-scores .leg-score-line.gold { + color: #b8860b; +} + +.node-leg-scores .leg-score-line.silver { + color: #607d8b; +} + /* Referral Code - only for club active members */ .node-referral { display: flex; diff --git a/src/FrontOffice.Main/wwwroot/js/org-chart.js b/src/FrontOffice.Main/wwwroot/js/org-chart.js index 0de2b93..9fb6c67 100644 --- a/src/FrontOffice.Main/wwwroot/js/org-chart.js +++ b/src/FrontOffice.Main/wwwroot/js/org-chart.js @@ -37,8 +37,8 @@ window.OrgChart = { this.chart = new d3.OrgChart() .container('#' + containerId) .data(data) - .nodeWidth((d) => 140) - .nodeHeight((d) => 85) + .nodeWidth((d) => 150) + .nodeHeight((d) => 112) .childrenMargin((d) => 50) .compactMarginBetween((d) => 15) .compactMarginPair((d) => 15) @@ -80,6 +80,16 @@ window.OrgChart = { ` : ''; + const gL = data.goldLeftLegTotal ?? 0; + const gR = data.goldRightLegTotal ?? 0; + const sL = data.silverLeftLegTotal ?? 0; + const sR = data.silverRightLegTotal ?? 0; + const legScoresHtml = ` +
+
طلایی: چپ ${gL} · راست ${gR}
+
نقره‌ای: چپ ${sL} · راست ${sR}
+
`; + return `
@@ -88,6 +98,7 @@ window.OrgChart = {
${data.fullName || 'بدون نام'}
L${data.level || 0}${!isRoot ? ' • ' + (data.position === 'Left' ? 'چپ' : 'راست') : ''}
${packageBadge} + ${legScoresHtml} ${referralCodeHtml}
From 101687f9dbcf3c57d6e722fdfb3ed0643c20074b Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Thu, 27 Aug 2026 21:30:06 +0330 Subject: [PATCH 3/6] feat(organization-chart): update statistics display and improve layout - Updated the organization chart to include additional statistics such as left and right leg counts, tree depth, and weaker leg identification for enhanced user insights. - Improved the layout and styling of the statistics bar for better visibility and user experience. - Adjusted the CSS for the organization chart to refine the overall presentation and responsiveness. These changes enhance the clarity and usability of the organization chart, providing users with essential metrics at a glance. --- src/FrontOffice.Main/FrontOffice.Main.csproj | 2 +- .../Components/OrganizationChart.razor | 54 +++++++++++------ .../Components/OrganizationChart.razor.cs | 6 +- .../Utilities/NetworkMembershipDtos.cs | 6 ++ .../Utilities/NetworkMembershipService.cs | 4 ++ .../wwwroot/css/org-chart.css | 58 ++++++++++++------- src/FrontOffice.Main/wwwroot/js/org-chart.js | 15 +---- 7 files changed, 87 insertions(+), 58 deletions(-) diff --git a/src/FrontOffice.Main/FrontOffice.Main.csproj b/src/FrontOffice.Main/FrontOffice.Main.csproj index b2ac49b..91e20bb 100644 --- a/src/FrontOffice.Main/FrontOffice.Main.csproj +++ b/src/FrontOffice.Main/FrontOffice.Main.csproj @@ -11,7 +11,7 @@ - + diff --git a/src/FrontOffice.Main/Pages/Profile/Components/OrganizationChart.razor b/src/FrontOffice.Main/Pages/Profile/Components/OrganizationChart.razor index 445b046..822efb6 100644 --- a/src/FrontOffice.Main/Pages/Profile/Components/OrganizationChart.razor +++ b/src/FrontOffice.Main/Pages/Profile/Components/OrganizationChart.razor @@ -52,29 +52,47 @@
} - @* Stats Bar *@ + @* Stats Bar — فقط آمار خود کاربر (نه نودهای درخت) *@ @if (_statistics != null && !_isLoading) {
-
- کل اعضا: - @_statistics.TotalMembers +
+
+ کل اعضا: + @_statistics.TotalMembers +
+
+ سازمان چپ: + @_statistics.LeftLegCount +
+
+ سازمان راست: + @_statistics.RightLegCount +
+
+ عمق: + @_statistics.TreeDepth +
+
+ پای ضعیف: + @(_statistics.WeakerLeg == "Left" ? "چپ" : "راست") +
-
- سازمان چپ: - @_statistics.LeftLegCount +
+
+ امتیاز طلایی: + چپ @_statistics.GoldLeftLegTotal + · + راست @_statistics.GoldRightLegTotal +
-
- سازمان راست: - @_statistics.RightLegCount -
-
- عمق: - @_statistics.TreeDepth -
-
- پای ضعیف: - @(_statistics.WeakerLeg == "Left" ? "چپ" : "راست") +
+
+ امتیاز نقره‌ای: + چپ @_statistics.SilverLeftLegTotal + · + راست @_statistics.SilverRightLegTotal +
} diff --git a/src/FrontOffice.Main/Pages/Profile/Components/OrganizationChart.razor.cs b/src/FrontOffice.Main/Pages/Profile/Components/OrganizationChart.razor.cs index 87e6719..4f6ac05 100644 --- a/src/FrontOffice.Main/Pages/Profile/Components/OrganizationChart.razor.cs +++ b/src/FrontOffice.Main/Pages/Profile/Components/OrganizationChart.razor.cs @@ -110,11 +110,7 @@ public partial class OrganizationChart : IAsyncDisposable activationWeekNumber = n.ActivationWeekNumber, joinedAt = n.JoinedAt, referralCode = n.ReferralCode, - packageName = n.PackageName ?? string.Empty, - goldLeftLegTotal = n.GoldLeftLegTotal, - goldRightLegTotal = n.GoldRightLegTotal, - silverLeftLegTotal = n.SilverLeftLegTotal, - silverRightLegTotal = n.SilverRightLegTotal + packageName = n.PackageName ?? string.Empty }).ToArray(); await JSRuntime.InvokeVoidAsync("OrgChart.init", "org-chart-container", flatData, _dotNetHelper); diff --git a/src/FrontOffice.Main/Utilities/NetworkMembershipDtos.cs b/src/FrontOffice.Main/Utilities/NetworkMembershipDtos.cs index 25a0664..eb655e8 100644 --- a/src/FrontOffice.Main/Utilities/NetworkMembershipDtos.cs +++ b/src/FrontOffice.Main/Utilities/NetworkMembershipDtos.cs @@ -152,4 +152,10 @@ public class NetworkStatisticsDto public int TreeDepth { get; set; } public string WeakerLeg { get; set; } = string.Empty; // "Left" or "Right" public LastMemberDto? LastMember { get; set; } + + /// آخرین امتیاز پای چپ/راست — فقط خود کاربر (نوار پایین شجره) + public int GoldLeftLegTotal { get; set; } + public int GoldRightLegTotal { get; set; } + public int SilverLeftLegTotal { get; set; } + public int SilverRightLegTotal { get; set; } } diff --git a/src/FrontOffice.Main/Utilities/NetworkMembershipService.cs b/src/FrontOffice.Main/Utilities/NetworkMembershipService.cs index 6bfa218..eb225d3 100644 --- a/src/FrontOffice.Main/Utilities/NetworkMembershipService.cs +++ b/src/FrontOffice.Main/Utilities/NetworkMembershipService.cs @@ -96,6 +96,10 @@ public class NetworkMembershipService TotalMembers = response.TotalMembers, TreeDepth = response.MaxDepth, WeakerLeg = response.WeakerLeg, + GoldLeftLegTotal = response.GoldLeftLegTotal, + GoldRightLegTotal = response.GoldRightLegTotal, + SilverLeftLegTotal = response.SilverLeftLegTotal, + SilverRightLegTotal = response.SilverRightLegTotal, LastMember = response.LastMember != null ? new LastMemberDto { UserId = response.LastMember.UserId, diff --git a/src/FrontOffice.Main/wwwroot/css/org-chart.css b/src/FrontOffice.Main/wwwroot/css/org-chart.css index b80b895..5b34af8 100644 --- a/src/FrontOffice.Main/wwwroot/css/org-chart.css +++ b/src/FrontOffice.Main/wwwroot/css/org-chart.css @@ -72,10 +72,10 @@ /* Compact Header */ .node-header-compact { display: flex; - align-items: flex-start; + align-items: center; gap: 6px; padding: 6px 8px; - min-height: 100%; + height: 100%; background: linear-gradient(135deg, #f8f9fa 0%, #fff 100%); } @@ -141,22 +141,7 @@ max-width: 120px; } -/* D3: طلایی / نقره‌ای — پای چپ و راست */ -.node-leg-scores { - margin-top: 3px; - line-height: 1.25; - font-size: 8px; - font-weight: 600; -} - -.node-leg-scores .leg-score-line.gold { - color: #b8860b; -} - -.node-leg-scores .leg-score-line.silver { - color: #607d8b; -} - +/* D3: امتیاز طلایی/نقره‌ای فقط در نوار پایین شجره (.org-chart-stats) */ /* Referral Code - only for club active members */ .node-referral { display: flex; @@ -386,14 +371,27 @@ /* Stats Bar */ .org-chart-stats { display: flex; + flex-direction: column; align-items: center; justify-content: center; - gap: 24px; + gap: 8px; padding: 12px 16px; background: #f8f9fa; border-top: 1px solid #e9ecef; } +.org-chart-stats-row { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: center; + gap: 24px; +} + +.org-chart-stats-row.leg-scores { + gap: 12px; +} + .stat-item { display: flex; align-items: center; @@ -401,6 +399,21 @@ font-size: 13px; } +.stat-item.leg-score-gold .stat-label { + color: #b8860b; + font-weight: 600; +} + +.stat-item.leg-score-silver .stat-label { + color: #607d8b; + font-weight: 600; +} + +.stat-sep { + color: #adb5bd; + margin: 0 2px; +} + .stat-label { color: #6c757d; } @@ -464,10 +477,13 @@ } .org-chart-stats { - flex-wrap: wrap; - gap: 12px; + gap: 8px; padding: 10px; } + + .org-chart-stats-row { + gap: 12px; + } .stat-item { font-size: 12px; diff --git a/src/FrontOffice.Main/wwwroot/js/org-chart.js b/src/FrontOffice.Main/wwwroot/js/org-chart.js index 9fb6c67..0de2b93 100644 --- a/src/FrontOffice.Main/wwwroot/js/org-chart.js +++ b/src/FrontOffice.Main/wwwroot/js/org-chart.js @@ -37,8 +37,8 @@ window.OrgChart = { this.chart = new d3.OrgChart() .container('#' + containerId) .data(data) - .nodeWidth((d) => 150) - .nodeHeight((d) => 112) + .nodeWidth((d) => 140) + .nodeHeight((d) => 85) .childrenMargin((d) => 50) .compactMarginBetween((d) => 15) .compactMarginPair((d) => 15) @@ -80,16 +80,6 @@ window.OrgChart = {
` : ''; - const gL = data.goldLeftLegTotal ?? 0; - const gR = data.goldRightLegTotal ?? 0; - const sL = data.silverLeftLegTotal ?? 0; - const sR = data.silverRightLegTotal ?? 0; - const legScoresHtml = ` -
-
طلایی: چپ ${gL} · راست ${gR}
-
نقره‌ای: چپ ${sL} · راست ${sR}
-
`; - return `
@@ -98,7 +88,6 @@ window.OrgChart = {
${data.fullName || 'بدون نام'}
L${data.level || 0}${!isRoot ? ' • ' + (data.position === 'Left' ? 'چپ' : 'راست') : ''}
${packageBadge} - ${legScoresHtml} ${referralCodeHtml}
From c6089f8dc36af05aa2a7ccf6e99c5b3dc1b2beaa Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Fri, 28 Aug 2026 18:56:34 +0330 Subject: [PATCH 4/6] refactor(organization-chart): update terminology and documentation for clarity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Changed terminology in the organization chart from "امتیاز" to "پکیج" for gold and silver packages to enhance clarity. - Updated comments and documentation in the codebase to reflect the new terminology and improve understanding of the statistics being displayed. - Adjusted the CHANGELOG to indicate the move of documentation to totalDoc. These changes improve the overall clarity and usability of the organization chart and related documentation. --- docs/CHANGELOG.md | 2 +- src/FrontOffice.Main/FrontOffice.Main.csproj | 5 ++--- .../Pages/Profile/Components/OrganizationChart.razor | 4 ++-- .../Utilities/NetworkMembershipDtos.cs | 10 +++++----- src/FrontOffice.Main/wwwroot/css/org-chart.css | 2 +- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 88d2fa8..0a43ad1 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,4 +1,4 @@ # Docs moved to totalDoc See [totalDoc/INDEX.md](../../totalDoc/INDEX.md) for all documentation. - \ No newline at end of file + \ No newline at end of file diff --git a/src/FrontOffice.Main/FrontOffice.Main.csproj b/src/FrontOffice.Main/FrontOffice.Main.csproj index 91e20bb..8d8f9e7 100644 --- a/src/FrontOffice.Main/FrontOffice.Main.csproj +++ b/src/FrontOffice.Main/FrontOffice.Main.csproj @@ -10,9 +10,8 @@ - - - + + diff --git a/src/FrontOffice.Main/Pages/Profile/Components/OrganizationChart.razor b/src/FrontOffice.Main/Pages/Profile/Components/OrganizationChart.razor index 822efb6..5d5cdf3 100644 --- a/src/FrontOffice.Main/Pages/Profile/Components/OrganizationChart.razor +++ b/src/FrontOffice.Main/Pages/Profile/Components/OrganizationChart.razor @@ -80,7 +80,7 @@
- امتیاز طلایی: + پکیج طلایی: چپ @_statistics.GoldLeftLegTotal · راست @_statistics.GoldRightLegTotal @@ -88,7 +88,7 @@
- امتیاز نقره‌ای: + پکیج نقره‌ای: چپ @_statistics.SilverLeftLegTotal · راست @_statistics.SilverRightLegTotal diff --git a/src/FrontOffice.Main/Utilities/NetworkMembershipDtos.cs b/src/FrontOffice.Main/Utilities/NetworkMembershipDtos.cs index eb655e8..cf10924 100644 --- a/src/FrontOffice.Main/Utilities/NetworkMembershipDtos.cs +++ b/src/FrontOffice.Main/Utilities/NetworkMembershipDtos.cs @@ -27,16 +27,16 @@ public class NetworkNodeDto ///
public string? PackageName { get; set; } - /// آخرین امتیاز پای چپ پکیج طلایی + /// تعداد اعضای فعال با پکیج طلایی جاری در پای چپ public int GoldLeftLegTotal { get; set; } - /// آخرین امتیاز پای راست پکیج طلایی + /// تعداد اعضای فعال با پکیج طلایی جاری در پای راست public int GoldRightLegTotal { get; set; } - /// آخرین امتیاز پای چپ پکیج نقره‌ای + /// تعداد اعضای فعال با پکیج نقره‌ای جاری در پای چپ public int SilverLeftLegTotal { get; set; } - /// آخرین امتیاز پای راست پکیج نقره‌ای + /// تعداد اعضای فعال با پکیج نقره‌ای جاری در پای راست public int SilverRightLegTotal { get; set; } } @@ -153,7 +153,7 @@ public class NetworkStatisticsDto public string WeakerLeg { get; set; } = string.Empty; // "Left" or "Right" public LastMemberDto? LastMember { get; set; } - /// آخرین امتیاز پای چپ/راست — فقط خود کاربر (نوار پایین شجره) + /// تعداد اعضای فعال با پکیج طلایی/نقره‌ای جاری در هر پا — نوار پایین شجره public int GoldLeftLegTotal { get; set; } public int GoldRightLegTotal { get; set; } public int SilverLeftLegTotal { get; set; } diff --git a/src/FrontOffice.Main/wwwroot/css/org-chart.css b/src/FrontOffice.Main/wwwroot/css/org-chart.css index 5b34af8..8a57707 100644 --- a/src/FrontOffice.Main/wwwroot/css/org-chart.css +++ b/src/FrontOffice.Main/wwwroot/css/org-chart.css @@ -141,7 +141,7 @@ max-width: 120px; } -/* D3: امتیاز طلایی/نقره‌ای فقط در نوار پایین شجره (.org-chart-stats) */ +/* D3: تعداد پکیج طلایی/نقره‌ای فقط در نوار پایین شجره (.org-chart-stats) */ /* Referral Code - only for club active members */ .node-referral { display: flex; From 186abe042f5104abc69be5aae6f2503e2910f90c Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Fri, 4 Sep 2026 04:14:36 +0330 Subject: [PATCH 5/6] feat(network-statistics): add total members and leg count properties with localization - Introduced new properties for total members, left leg count, and right leg count in the NetworkStatisticsDto class to enhance data representation. - Added localization comments in Persian for better understanding of the new properties. - Updated the .gitignore file to ensure consistency with the latest Visual Studio ignore patterns. These changes improve the clarity and usability of the network statistics, providing a more comprehensive view of member distribution. --- .gitignore | 2 +- src/FrontOffice.Main/Utilities/NetworkMembershipDtos.cs | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 1c55f34..0f13c79 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. ## -## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore +## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore # User-specific files *.rsuser diff --git a/src/FrontOffice.Main/Utilities/NetworkMembershipDtos.cs b/src/FrontOffice.Main/Utilities/NetworkMembershipDtos.cs index cf10924..a6c2128 100644 --- a/src/FrontOffice.Main/Utilities/NetworkMembershipDtos.cs +++ b/src/FrontOffice.Main/Utilities/NetworkMembershipDtos.cs @@ -146,8 +146,11 @@ public class LastMemberDto /// public class NetworkStatisticsDto { + /// اعضای فعال باشگاه در پای چپ public int LeftLegCount { get; set; } + /// اعضای فعال باشگاه در پای راست public int RightLegCount { get; set; } + /// LeftLegCount + RightLegCount public int TotalMembers { get; set; } public int TreeDepth { get; set; } public string WeakerLeg { get; set; } = string.Empty; // "Left" or "Right" From 8252e408b647f0d2e7972d23b325c12f2ca8666e Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Fri, 4 Sep 2026 06:48:24 +0330 Subject: [PATCH 6/6] feat(organization-chart): update registration date handling and styling - Modified the OrganizationChart component to convert and display the registration date in Jalali format, enhancing user understanding of the date information. - Updated the NetworkMembershipDtos class to include a comment in Persian for the JoinedAt property, clarifying its purpose. - Adjusted the NetworkMembershipService to utilize the UserCreated date when available, improving data accuracy. - Introduced new CSS styles for the registration date display, ensuring better visibility and presentation in the organization chart. These changes enhance the clarity and usability of the organization chart by providing accurate registration date information in a user-friendly format. --- .../Profile/Components/OrganizationChart.razor.cs | 5 ++++- .../Utilities/NetworkMembershipDtos.cs | 2 +- .../Utilities/NetworkMembershipService.cs | 3 ++- src/FrontOffice.Main/wwwroot/css/org-chart.css | 10 ++++++++++ src/FrontOffice.Main/wwwroot/js/org-chart.js | 5 +++-- 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/FrontOffice.Main/Pages/Profile/Components/OrganizationChart.razor.cs b/src/FrontOffice.Main/Pages/Profile/Components/OrganizationChart.razor.cs index 4f6ac05..22e34b0 100644 --- a/src/FrontOffice.Main/Pages/Profile/Components/OrganizationChart.razor.cs +++ b/src/FrontOffice.Main/Pages/Profile/Components/OrganizationChart.razor.cs @@ -1,3 +1,4 @@ +using DateTimeConverterCL; using FrontOffice.Main.Utilities; using Microsoft.AspNetCore.Components; using Microsoft.JSInterop; @@ -108,7 +109,9 @@ public partial class OrganizationChart : IAsyncDisposable isActive = n.IsActive, isClubActive = n.IsClubActive, activationWeekNumber = n.ActivationWeekNumber, - joinedAt = n.JoinedAt, + registeredAt = n.JoinedAt.HasValue + ? n.JoinedAt.Value.ToLocalTime().MiladiToJalali() + : "", referralCode = n.ReferralCode, packageName = n.PackageName ?? string.Empty }).ToArray(); diff --git a/src/FrontOffice.Main/Utilities/NetworkMembershipDtos.cs b/src/FrontOffice.Main/Utilities/NetworkMembershipDtos.cs index a6c2128..54646a9 100644 --- a/src/FrontOffice.Main/Utilities/NetworkMembershipDtos.cs +++ b/src/FrontOffice.Main/Utilities/NetworkMembershipDtos.cs @@ -14,7 +14,7 @@ public class NetworkNodeDto public NetworkNodeDto? RightChild { get; set; } public int Level { get; set; } public bool IsActive { get; set; } = true; - public DateTime? JoinedAt { get; set; } + public DateTime? JoinedAt { get; set; } // تاریخ ثبت‌نام (UserCreated) public bool IsClubActive { get; set; } public string? ActivationWeekNumber { get; set; } /// diff --git a/src/FrontOffice.Main/Utilities/NetworkMembershipService.cs b/src/FrontOffice.Main/Utilities/NetworkMembershipService.cs index eb225d3..92e11df 100644 --- a/src/FrontOffice.Main/Utilities/NetworkMembershipService.cs +++ b/src/FrontOffice.Main/Utilities/NetworkMembershipService.cs @@ -147,7 +147,8 @@ public class NetworkMembershipService SilverLeftLegTotal = node.SilverLeftLegTotal, SilverRightLegTotal = node.SilverRightLegTotal, ActivationWeekNumber = node.ActivationWeekDefinitionId?.ToString(), - JoinedAt = node.JoinedAt?.ToDateTime(), + JoinedAt = node.UserCreated?.ToDateTime() + ?? node.JoinedAt?.ToDateTime(), LeftChild = MapNodeFromProto(node.LeftChild), RightChild = MapNodeFromProto(node.RightChild) }; diff --git a/src/FrontOffice.Main/wwwroot/css/org-chart.css b/src/FrontOffice.Main/wwwroot/css/org-chart.css index 8a57707..b5124d8 100644 --- a/src/FrontOffice.Main/wwwroot/css/org-chart.css +++ b/src/FrontOffice.Main/wwwroot/css/org-chart.css @@ -118,6 +118,16 @@ line-height: 1.2; } +.node-registered-at { + font-size: 8px; + color: #6c757d; + margin-top: 1px; + line-height: 1.2; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + .node-level-sm { font-size: 9px; color: #6c757d; diff --git a/src/FrontOffice.Main/wwwroot/js/org-chart.js b/src/FrontOffice.Main/wwwroot/js/org-chart.js index 0de2b93..19c56f5 100644 --- a/src/FrontOffice.Main/wwwroot/js/org-chart.js +++ b/src/FrontOffice.Main/wwwroot/js/org-chart.js @@ -38,7 +38,7 @@ window.OrgChart = { .container('#' + containerId) .data(data) .nodeWidth((d) => 140) - .nodeHeight((d) => 85) + .nodeHeight((d) => 98) .childrenMargin((d) => 50) .compactMarginBetween((d) => 15) .compactMarginPair((d) => 15) @@ -86,6 +86,7 @@ window.OrgChart = {
${firstChar}
${data.fullName || 'بدون نام'}
+ ${data.registeredAt ? `
${data.registeredAt}
` : ''}
L${data.level || 0}${!isRoot ? ' • ' + (data.position === 'Left' ? 'چپ' : 'راست') : ''}
${packageBadge} ${referralCodeHtml} @@ -296,7 +297,7 @@ window.OrgChart = { isActive: node.isActive !== false, isClubActive: node.isClubActive || false, activationWeekNumber: node.activationWeekNumber, - joinedAt: node.joinedAt + registeredAt: node.registeredAt || node.joinedAt || '' }; result.push(flatNode);