148 lines
3.1 KiB
TypeScript
148 lines
3.1 KiB
TypeScript
'use client'
|
|
|
|
import { useQuery } from '@tanstack/react-query';
|
|
import { fetchReferralsLevels, fetchReferralUserStats } from '@/app/actions/referralsActions';
|
|
|
|
interface ReferralLevel {
|
|
name: string;
|
|
id: string;
|
|
next: string | null;
|
|
share: number;
|
|
maxInvitee: number;
|
|
minInvitee: number;
|
|
}
|
|
|
|
interface ReferralsData {
|
|
referrals: ReferralLevel[];
|
|
}
|
|
|
|
export default function CommissionLevels() {
|
|
|
|
const {
|
|
data: referralsLevels,
|
|
isLoading,
|
|
isError,
|
|
error
|
|
} = useQuery<ReferralsData, Error, ReferralLevel[]>({
|
|
queryKey: ['referralsLevels'],
|
|
queryFn: () => fetchReferralsLevels(),
|
|
select: (data) => {
|
|
if (data?.referrals) {
|
|
const itemsMap = new Map<string, ReferralLevel>();
|
|
data.referrals.forEach(item => {
|
|
itemsMap.set(item.id, item);
|
|
});
|
|
|
|
const referencedIds = new Set(
|
|
data.referrals
|
|
.map(item => item.next)
|
|
.filter((next): next is string => next !== null)
|
|
);
|
|
|
|
const firstItem = data.referrals.find(item => !referencedIds.has(item.id));
|
|
|
|
if (!firstItem) {
|
|
return [];
|
|
}
|
|
|
|
const sortedReferrals: ReferralLevel[] = [];
|
|
let currentItem = firstItem;
|
|
|
|
while (currentItem) {
|
|
sortedReferrals.push(currentItem);
|
|
|
|
if (currentItem.next === null) {
|
|
break;
|
|
}
|
|
|
|
currentItem = itemsMap.get(currentItem.next)!;
|
|
|
|
if (sortedReferrals.includes(currentItem)) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return sortedReferrals;
|
|
} else {
|
|
return [];
|
|
}
|
|
}
|
|
});
|
|
|
|
const {
|
|
data: activeInvites,
|
|
error: activeInvitesError
|
|
} = useQuery({
|
|
queryKey: ['referralUserStats'],
|
|
queryFn: () => {
|
|
return fetchReferralUserStats();
|
|
},
|
|
select: (data) => {
|
|
if (data?.activeInvitee) {
|
|
return data.activeInvitee
|
|
} else {
|
|
return 0
|
|
};
|
|
}
|
|
});
|
|
|
|
if (!referralsLevels?.length) {
|
|
return null;
|
|
}
|
|
|
|
function getReferralIcon(referral: string) {
|
|
switch (referral) {
|
|
case 'bronze':
|
|
return '🥉'
|
|
case 'silver':
|
|
return '🥈'
|
|
case 'gold':
|
|
return '🥇'
|
|
case 'platinum':
|
|
return '💎'
|
|
default:
|
|
return '🥉'
|
|
}
|
|
}
|
|
|
|
function isActiveReferralLevel(activeInvites: number, maxInvites: number, minInvites: number) {
|
|
if (activeInvites <= maxInvites && activeInvites >= minInvites) {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className="block-wrapper">
|
|
<h3 className="section-title">
|
|
<span className="icon"></span>
|
|
Уровни комиссии
|
|
</h3>
|
|
<div className="commission-levels">
|
|
{
|
|
referralsLevels.map((item: ReferralLevel) => {
|
|
return (
|
|
<div
|
|
className={
|
|
`level-card ${isActiveReferralLevel(activeInvites, item.maxInvitee, item.minInvitee) ? 'active' : ''}`
|
|
}
|
|
key={item.id}
|
|
>
|
|
<div className="level-number">
|
|
{getReferralIcon(item.id)}
|
|
</div>
|
|
<div className="level-commission">{item.share}%</div>
|
|
<div className="level-subscribe">{item.name}</div>
|
|
<div className="level-requirement">{
|
|
item.maxInvitee < 100 ? `${item.minInvitee}-${item.maxInvitee}` : `${item.minInvitee}+`
|
|
} рефералов
|
|
</div>
|
|
</div>
|
|
)
|
|
})
|
|
}
|
|
</div>
|
|
</div>
|
|
)
|
|
} |