feat: update NetworkMembership Protobuf version and add referral code functionality with UI enhancements
Build and Deploy to Production / build-and-deploy (push) Has been cancelled
Build and Deploy to Production / build-and-deploy (push) Has been cancelled
This commit is contained in:
@@ -17,7 +17,7 @@
|
|||||||
<!-- <PackageReference Include="Foursat.FrontOffice.BFF.ClubMembership.Protobuf" Version="0.0.3" /> -->
|
<!-- <PackageReference Include="Foursat.FrontOffice.BFF.ClubMembership.Protobuf" Version="0.0.3" /> -->
|
||||||
<!-- <PackageReference Include="Foursat.FrontOffice.BFF.Commission.Protobuf" Version="0.0.2" /> -->
|
<!-- <PackageReference Include="Foursat.FrontOffice.BFF.Commission.Protobuf" Version="0.0.2" /> -->
|
||||||
<PackageReference Include="Foursat.FrontOffice.BFF.DiscountShop.Protobuf" Version="0.0.3" />
|
<PackageReference Include="Foursat.FrontOffice.BFF.DiscountShop.Protobuf" Version="0.0.3" />
|
||||||
<PackageReference Include="Foursat.FrontOffice.BFF.NetworkMembership.Protobuf" Version="0.0.4" />
|
<PackageReference Include="Foursat.FrontOffice.BFF.NetworkMembership.Protobuf" Version="0.0.5" />
|
||||||
<PackageReference Include="Foursat.FrontOffice.BFF.Package.Protobuf" Version="0.0.114" />
|
<PackageReference Include="Foursat.FrontOffice.BFF.Package.Protobuf" Version="0.0.114" />
|
||||||
<!-- <PackageReference Include="Foursat.FrontOffice.BFF.NetworkMembership.Protobuf" Version="0.0.2" />-->
|
<!-- <PackageReference Include="Foursat.FrontOffice.BFF.NetworkMembership.Protobuf" Version="0.0.2" />-->
|
||||||
<!-- <PackageReference Include="Foursat.FrontOffice.BFF.Package.Protobuf" Version="0.0.113" /> -->
|
<!-- <PackageReference Include="Foursat.FrontOffice.BFF.Package.Protobuf" Version="0.0.113" /> -->
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ public class NetworkNodeDto
|
|||||||
public DateTime? JoinedAt { get; set; }
|
public DateTime? JoinedAt { get; set; }
|
||||||
public bool IsClubActive { get; set; }
|
public bool IsClubActive { get; set; }
|
||||||
public string? ActivationWeekNumber { get; set; }
|
public string? ActivationWeekNumber { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// کد معرف کاربر
|
||||||
|
/// </summary>
|
||||||
|
public string? ReferralCode { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -35,6 +39,10 @@ public class FlatNetworkNodeDto
|
|||||||
public bool IsClubActive { get; set; }
|
public bool IsClubActive { get; set; }
|
||||||
public string? ActivationWeekNumber { get; set; }
|
public string? ActivationWeekNumber { get; set; }
|
||||||
public DateTime? JoinedAt { get; set; }
|
public DateTime? JoinedAt { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// کد معرف کاربر - فقط برای کاربران فعال در باشگاه نمایش داده شود
|
||||||
|
/// </summary>
|
||||||
|
public string? ReferralCode { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -72,7 +80,8 @@ public class NetworkTreeDto
|
|||||||
IsActive = node.IsActive,
|
IsActive = node.IsActive,
|
||||||
IsClubActive = node.IsClubActive,
|
IsClubActive = node.IsClubActive,
|
||||||
ActivationWeekNumber = node.ActivationWeekNumber,
|
ActivationWeekNumber = node.ActivationWeekNumber,
|
||||||
JoinedAt = node.JoinedAt
|
JoinedAt = node.JoinedAt,
|
||||||
|
ReferralCode = node.ReferralCode
|
||||||
};
|
};
|
||||||
|
|
||||||
result.Add(flatNode);
|
result.Add(flatNode);
|
||||||
|
|||||||
@@ -414,3 +414,69 @@
|
|||||||
overflow: visible;
|
overflow: visible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Referral Code Style */
|
||||||
|
.node-referral {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 3px;
|
||||||
|
margin-top: 2px;
|
||||||
|
padding: 2px 4px;
|
||||||
|
background: linear-gradient(135deg, #fff3e0 0%, #ffe0b2 100%);
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-referral:hover {
|
||||||
|
background: linear-gradient(135deg, #ffe0b2 0%, #ffcc80 100%);
|
||||||
|
transform: scale(1.02);
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-referral .referral-icon {
|
||||||
|
font-size: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-referral .referral-code {
|
||||||
|
font-size: 8px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #e65100;
|
||||||
|
font-family: monospace;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Club Active Badge */
|
||||||
|
.org-node-card.club-active {
|
||||||
|
border-right: 3px solid #ff9800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.org-node-card.club-active .node-avatar-sm {
|
||||||
|
background: linear-gradient(135deg, #ff9800 0%, #f57c00 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Toast Notification */
|
||||||
|
.org-chart-toast {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 20px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%) translateY(100px);
|
||||||
|
background: #323232;
|
||||||
|
color: white;
|
||||||
|
padding: 12px 24px;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: 'Vazirmatn', sans-serif;
|
||||||
|
direction: rtl;
|
||||||
|
z-index: 10000;
|
||||||
|
opacity: 0;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.org-chart-toast.show {
|
||||||
|
transform: translateX(-50%) translateY(0);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|||||||
@@ -59,17 +59,27 @@ window.OrgChart = {
|
|||||||
const positionClass = data.position === 'Left' ? 'position-left' :
|
const positionClass = data.position === 'Left' ? 'position-left' :
|
||||||
data.position === 'Right' ? 'position-right' : 'position-root';
|
data.position === 'Right' ? 'position-right' : 'position-root';
|
||||||
const activeClass = data.isActive ? 'active' : 'inactive';
|
const activeClass = data.isActive ? 'active' : 'inactive';
|
||||||
|
const clubActiveClass = data.isClubActive ? 'club-active' : '';
|
||||||
|
|
||||||
// Avatar - first letter of name
|
// Avatar - first letter of name
|
||||||
const firstChar = data.fullName ? data.fullName.charAt(0) : '?';
|
const firstChar = data.fullName ? data.fullName.charAt(0) : '?';
|
||||||
|
|
||||||
|
// نمایش کد معرف فقط برای کاربران فعال در باشگاه
|
||||||
|
const referralCodeHtml = data.isClubActive && data.referralCode
|
||||||
|
? `<div class="node-referral" onclick="event.stopPropagation(); OrgChart.copyReferralCode('${data.referralCode}');" title="کپی کد معرف">
|
||||||
|
<span class="referral-icon">📋</span>
|
||||||
|
<span class="referral-code">${data.referralCode}</span>
|
||||||
|
</div>`
|
||||||
|
: '';
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="org-node-card ${positionClass} ${activeClass}" data-user-id="${data.id}">
|
<div class="org-node-card ${positionClass} ${activeClass} ${clubActiveClass}" data-user-id="${data.id}">
|
||||||
<div class="node-header-compact ${isRoot ? 'root' : ''}">
|
<div class="node-header-compact ${isRoot ? 'root' : ''}">
|
||||||
<div class="node-avatar-sm">${firstChar}</div>
|
<div class="node-avatar-sm">${firstChar}</div>
|
||||||
<div class="node-info">
|
<div class="node-info">
|
||||||
<div class="node-name-sm">${data.fullName || 'بدون نام'}</div>
|
<div class="node-name-sm">${data.fullName || 'بدون نام'}</div>
|
||||||
<div class="node-level-sm">L${data.level || 0}${!isRoot ? ' • ' + (data.position === 'Left' ? 'چپ' : 'راست') : ''}</div>
|
<div class="node-level-sm">L${data.level || 0}${!isRoot ? ' • ' + (data.position === 'Left' ? 'چپ' : 'راست') : ''}</div>
|
||||||
|
${referralCodeHtml}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -187,6 +197,63 @@ window.OrgChart = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy referral code to clipboard
|
||||||
|
* @param {string} code - The referral code to copy
|
||||||
|
*/
|
||||||
|
copyReferralCode: function(code) {
|
||||||
|
if (navigator.clipboard) {
|
||||||
|
navigator.clipboard.writeText(code).then(() => {
|
||||||
|
// Show toast notification
|
||||||
|
this.showToast('کد معرف کپی شد: ' + code);
|
||||||
|
}).catch(err => {
|
||||||
|
console.error('Failed to copy:', err);
|
||||||
|
this.fallbackCopy(code);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.fallbackCopy(code);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fallback copy method for older browsers
|
||||||
|
*/
|
||||||
|
fallbackCopy: function(text) {
|
||||||
|
const textArea = document.createElement('textarea');
|
||||||
|
textArea.value = text;
|
||||||
|
textArea.style.position = 'fixed';
|
||||||
|
textArea.style.left = '-999999px';
|
||||||
|
document.body.appendChild(textArea);
|
||||||
|
textArea.select();
|
||||||
|
try {
|
||||||
|
document.execCommand('copy');
|
||||||
|
this.showToast('کد معرف کپی شد: ' + text);
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Fallback copy failed:', err);
|
||||||
|
}
|
||||||
|
document.body.removeChild(textArea);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show toast notification
|
||||||
|
*/
|
||||||
|
showToast: function(message) {
|
||||||
|
// Remove existing toast
|
||||||
|
const existingToast = document.querySelector('.org-chart-toast');
|
||||||
|
if (existingToast) existingToast.remove();
|
||||||
|
|
||||||
|
const toast = document.createElement('div');
|
||||||
|
toast.className = 'org-chart-toast';
|
||||||
|
toast.textContent = message;
|
||||||
|
document.body.appendChild(toast);
|
||||||
|
|
||||||
|
setTimeout(() => toast.classList.add('show'), 10);
|
||||||
|
setTimeout(() => {
|
||||||
|
toast.classList.remove('show');
|
||||||
|
setTimeout(() => toast.remove(), 300);
|
||||||
|
}, 2000);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispose the chart
|
* Dispose the chart
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user