diff --git a/src/BackOffice/BackOffice.csproj b/src/BackOffice/BackOffice.csproj index b204838..b9d23cf 100644 --- a/src/BackOffice/BackOffice.csproj +++ b/src/BackOffice/BackOffice.csproj @@ -134,9 +134,9 @@ - + - + diff --git a/src/BackOffice/Pages/Commission/UserPayouts.razor b/src/BackOffice/Pages/Commission/UserPayouts.razor index 04af097..ecfea3b 100644 --- a/src/BackOffice/Pages/Commission/UserPayouts.razor +++ b/src/BackOffice/Pages/Commission/UserPayouts.razor @@ -74,14 +74,14 @@ - @context.Item.ValuePerBalance.ToString("N0") ریال + @context.Item.ValuePerBalance.ToString("N0") - @context.Item.TotalAmount.ToString("N0") ریال + @context.Item.TotalAmount.ToString("N0") diff --git a/src/BackOffice/Pages/Network/NetworkTreeViewer.razor b/src/BackOffice/Pages/Network/NetworkTreeViewer.razor index 105d172..fcd3ec2 100644 --- a/src/BackOffice/Pages/Network/NetworkTreeViewer.razor +++ b/src/BackOffice/Pages/Network/NetworkTreeViewer.razor @@ -9,7 +9,7 @@ درخت شبکه - +
@@ -21,6 +21,21 @@ Disabled="_isLoading"> نمایش درخت + + + +
+ + همه + فعال + غیرفعال + +
+ +
+ +
@@ -67,17 +82,13 @@ - + - @if (context.Item.IsActive!=null) - { - - @((bool)context.Item.IsActive ? "فعال" : "غیرفعال") + @(context.Item.IsClubActive ? "فعال" : "غیرفعال") - } @@ -94,6 +105,45 @@ + + + @if (context.Item.IsClubActive) + { + فعال + } + else + { + غیرفعال + } + + + + + + @if (!string.IsNullOrEmpty(context.Item.ActivationWeekNumber)) + { + @context.Item.ActivationWeekNumber + } + else + { + - + } + + + + + + @if (context.Item.ClubActivatedAt != null) + { + @context.Item.ClubActivatedAt.ToDateTime().ToLocalTime().ToString("yyyy/MM/dd") + } + else + { + - + } + + + _dotNetRef; + private bool? _clubActiveFilter; + private string? _activationWeekFilter; protected override void OnInitialized() { @@ -156,7 +208,13 @@ try { - var request = new GetNetworkTreeRequest { UserId = _searchUserId.Value, MaxDepth = 20 }; + var request = new GetNetworkTreeRequest + { + UserId = _searchUserId.Value, + MaxDepth = 20, + IsClubActive = _clubActiveFilter.HasValue ? _clubActiveFilter.Value : null, + ActivationWeekNumber = !string.IsNullOrEmpty(_activationWeekFilter) ? _activationWeekFilter : null + }; _treeData = await NetworkContract.GetNetworkTreeAsync(request); CalculateStats(); @@ -187,7 +245,12 @@ parentId = n.ParentId, networkLevel = n.NetworkLevel, networkLeg = n.NetworkLeg, - isActive = n.IsActive ?? false + isActive = n.IsClubActive, + isClubActive = n.IsClubActive, + isActivatedInTargetWeek = n.IsActivatedInTargetWeek, + activationWeekNumber = _activationWeekFilter ?? "", // فیلتر UI + clubActivatedAt = n.ClubActivatedAt?.ToDateTime().ToLocalTime().ToString("yyyy/MM/dd") ?? "", + userCreated = n.UserCreated?.ToDateTime().ToLocalTime().ToString("yyyy/MM/dd") ?? "" }).ToArray(); await JS.InvokeVoidAsync("NetworkTreeViewer.initialize", "network-tree-container", jsNodes); diff --git a/src/BackOffice/wwwroot/js/network-tree.js b/src/BackOffice/wwwroot/js/network-tree.js index c9578dd..bd76c88 100644 --- a/src/BackOffice/wwwroot/js/network-tree.js +++ b/src/BackOffice/wwwroot/js/network-tree.js @@ -102,7 +102,14 @@ window.NetworkTreeViewer = { // Add circles for nodes node.append('circle') .attr('r', 8) - .style('fill', d => d.data.isActive ? '#4caf50' : '#f44336') + .style('fill', d => { + // اگر هفته‌ای انتخاب نشده، همه سبز + if (!d.data.activationWeekNumber || d.data.activationWeekNumber === '') { + return '#4caf50'; + } + // اگر در هفته هدف فعال شده، سبز، وگرنه قرمز + return d.data.isActivatedInTargetWeek ? '#4caf50' : '#f44336'; + }) .style('stroke', '#fff') .style('stroke-width', 2) .style('cursor', 'pointer') @@ -118,7 +125,7 @@ window.NetworkTreeViewer = { .attr('text-anchor', 'middle') .style('font-size', '12px') .style('font-weight', 'bold') - .style('fill', '#333') + .style('fill', d => d.data.isClubActive ? '#424242' : '#9e9e9e') .text(d => d.data.userName || `User ${d.data.userId}`); // Add level info @@ -137,33 +144,73 @@ window.NetworkTreeViewer = { .style('fill', d => d.data.networkLeg === 0 ? '#4caf50' : '#ff9800') .text(d => d.data.networkLeg === 0 ? 'چپ' : 'راست'); + // Enhanced tooltip with club info + node.append('title') + .text(d => { + let tooltip = `نام: ${d.data.userName || 'User ' + d.data.userId}\nسطح: ${d.data.level}\nپایه: ${d.data.networkLeg === 0 ? 'چپ' : 'راست'}`; + + if (d.data.userCreated) { + tooltip += `\nتاریخ ثبت‌نام: ${d.data.userCreated}`; + } + + tooltip += `\nوضعیت باشگاه: ${d.data.isClubActive ? 'فعال' : 'غیرفعال'}`; + + if (d.data.clubActivatedAt) { + tooltip += `\nتاریخ فعالسازی باشگاه: ${d.data.clubActivatedAt}`; + } + + if (d.data.activationWeekNumber) { + tooltip += `\nهفته فعالسازی: ${d.data.activationWeekNumber}`; + } + + return tooltip; + }); + // Add legend const legend = svg.append('g') - .attr('transform', `translate(${width - 150}, 20)`); + .attr('transform', `translate(${width - 180}, 20)`); + // Legend for title colors (club status) + legend.append('text') + .attr('x', 0) + .attr('y', 0) + .style('font-size', '12px') + .style('font-weight', 'bold') + .style('fill', '#424242') + .text('باشگاه فعال'); + + legend.append('text') + .attr('x', 0) + .attr('y', 20) + .style('font-size', '12px') + .style('font-weight', 'bold') + .style('fill', '#9e9e9e') + .text('باشگاه غیرفعال'); + + // Legend for circles (week status) legend.append('circle') .attr('cx', 0) - .attr('cy', 0) + .attr('cy', 50) .attr('r', 6) .style('fill', '#4caf50'); legend.append('text') .attr('x', 12) - .attr('y', 4) + .attr('y', 54) .style('font-size', '12px') - .text('فعال'); + .text('فعال در هفته هدف'); legend.append('circle') .attr('cx', 0) - .attr('cy', 25) + .attr('cy', 75) .attr('r', 6) .style('fill', '#f44336'); legend.append('text') .attr('x', 12) - .attr('y', 29) + .attr('y', 79) .style('font-size', '12px') - .text('غیرفعال'); + .text('خارج از هفته هدف'); }, buildHierarchy: function(nodes) { @@ -181,6 +228,11 @@ window.NetworkTreeViewer = { level: node.networkLevel, networkLeg: node.networkLeg, isActive: node.isActive, + isClubActive: node.isClubActive, + isActivatedInTargetWeek: node.isActivatedInTargetWeek, + activationWeekNumber: node.activationWeekNumber, + clubActivatedAt: node.clubActivatedAt, + userCreated: node.userCreated, children: [] }); });