Add incremental loading to manager and client lists
This commit is contained in:
@@ -56,33 +56,40 @@ const referralLinksByReferrer = computed(() => {
|
||||
const filteredBalances = computed(() => {
|
||||
const query = search.value.trim().toLowerCase();
|
||||
|
||||
return balances.value.filter((item) => {
|
||||
const links = referralLinksByReferrer.value.get(item.userId);
|
||||
return balances.value
|
||||
.filter((item) => {
|
||||
const links = referralLinksByReferrer.value.get(item.userId);
|
||||
|
||||
if (!links?.length) {
|
||||
return false;
|
||||
}
|
||||
if (!links?.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!query) {
|
||||
return true;
|
||||
}
|
||||
if (!query) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return [
|
||||
item.fullName,
|
||||
item.email,
|
||||
item.companyName || '',
|
||||
String(item.balance),
|
||||
...links.flatMap((link) => [
|
||||
link.refereeName,
|
||||
link.refereeEmail,
|
||||
link.refereeCompanyName || '',
|
||||
String(link.bonusPercent),
|
||||
]),
|
||||
]
|
||||
.join(' ')
|
||||
.toLowerCase()
|
||||
.includes(query);
|
||||
});
|
||||
return [
|
||||
item.fullName,
|
||||
item.email,
|
||||
item.companyName || '',
|
||||
String(item.balance),
|
||||
...links.flatMap((link) => [
|
||||
link.refereeName,
|
||||
link.refereeEmail,
|
||||
link.refereeCompanyName || '',
|
||||
String(link.bonusPercent),
|
||||
]),
|
||||
]
|
||||
.join(' ')
|
||||
.toLowerCase()
|
||||
.includes(query);
|
||||
})
|
||||
.slice()
|
||||
.sort((left, right) => {
|
||||
const leftLatest = referralLinksByReferrer.value.get(left.userId)?.[0]?.createdAt ?? '';
|
||||
const rightLatest = referralLinksByReferrer.value.get(right.userId)?.[0]?.createdAt ?? '';
|
||||
return rightLatest.localeCompare(leftLatest);
|
||||
});
|
||||
});
|
||||
|
||||
const filteredWithdrawals = computed(() => {
|
||||
@@ -107,6 +114,30 @@ const filteredWithdrawals = computed(() => {
|
||||
});
|
||||
});
|
||||
|
||||
const {
|
||||
canLoadMore: canLoadMoreBalances,
|
||||
loadMore: loadMoreBalances,
|
||||
loadMoreSentinel: loadMoreBalancesSentinel,
|
||||
remainingCount: remainingBalancesCount,
|
||||
visibleItems: visibleBalances,
|
||||
} = useIncrementalList(filteredBalances, {
|
||||
pageSize: 24,
|
||||
enabled: computed(() => activeTab.value === 'balances'),
|
||||
resetKeys: [search, activeTab],
|
||||
});
|
||||
|
||||
const {
|
||||
canLoadMore: canLoadMoreWithdrawals,
|
||||
loadMore: loadMoreWithdrawals,
|
||||
loadMoreSentinel: loadMoreWithdrawalsSentinel,
|
||||
remainingCount: remainingWithdrawalsCount,
|
||||
visibleItems: visibleWithdrawals,
|
||||
} = useIncrementalList(filteredWithdrawals, {
|
||||
pageSize: 24,
|
||||
enabled: computed(() => activeTab.value === 'withdrawals'),
|
||||
resetKeys: [search, activeTab],
|
||||
});
|
||||
|
||||
function userInitials(fullName: string) {
|
||||
const parts = fullName
|
||||
.trim()
|
||||
@@ -150,17 +181,29 @@ function formatAmount(value: number) {
|
||||
<div v-else-if="filteredBalances.length === 0" class="manager-empty-state">
|
||||
Бонусных связок пока нет.
|
||||
</div>
|
||||
<div v-else class="grid gap-4 sm:grid-cols-2 xl:grid-cols-4 2xl:grid-cols-6">
|
||||
<UsersGridCard
|
||||
v-for="item in filteredBalances"
|
||||
:key="item.userId"
|
||||
:to="`/bonus-system/${item.userId}`"
|
||||
:full-name="item.fullName"
|
||||
:avatar-src="messengerConnectionAvatarSrc(usersById.get(item.userId)?.telegramConnection)"
|
||||
:initials="userInitials(item.fullName)"
|
||||
meta-label="Доступный бонус"
|
||||
:meta-value="formatAmount(item.balance)"
|
||||
/>
|
||||
<div v-else class="space-y-4">
|
||||
<div class="grid gap-4 sm:grid-cols-2 xl:grid-cols-4 2xl:grid-cols-6">
|
||||
<UsersGridCard
|
||||
v-for="item in visibleBalances"
|
||||
:key="item.userId"
|
||||
:to="`/bonus-system/${item.userId}`"
|
||||
:full-name="item.fullName"
|
||||
:avatar-src="messengerConnectionAvatarSrc(usersById.get(item.userId)?.telegramConnection)"
|
||||
:initials="userInitials(item.fullName)"
|
||||
meta-label="Доступный бонус"
|
||||
:meta-value="formatAmount(item.balance)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="canLoadMoreBalances"
|
||||
ref="loadMoreBalancesSentinel"
|
||||
class="flex justify-center"
|
||||
>
|
||||
<button class="btn btn-outline border-[#d7e9de] bg-white" @click="loadMoreBalances">
|
||||
Показать ещё {{ Math.min(remainingBalancesCount, 24) }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -173,7 +216,7 @@ function formatAmount(value: number) {
|
||||
</div>
|
||||
<div v-else class="space-y-4">
|
||||
<article
|
||||
v-for="withdrawal in filteredWithdrawals"
|
||||
v-for="withdrawal in visibleWithdrawals"
|
||||
:key="withdrawal.id"
|
||||
class="surface-card rounded-3xl px-5 py-5"
|
||||
>
|
||||
@@ -190,6 +233,16 @@ function formatAmount(value: number) {
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<div
|
||||
v-if="canLoadMoreWithdrawals"
|
||||
ref="loadMoreWithdrawalsSentinel"
|
||||
class="flex justify-center"
|
||||
>
|
||||
<button class="btn btn-outline border-[#d7e9de] bg-white" @click="loadMoreWithdrawals">
|
||||
Показать ещё {{ Math.min(remainingWithdrawalsCount, 24) }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</section>
|
||||
|
||||
Reference in New Issue
Block a user