Skip to content

Commit b54e4ab

Browse files
committed
feat: pagination of invitees list
1 parent c66dc69 commit b54e4ab

File tree

8 files changed

+153
-34
lines changed

8 files changed

+153
-34
lines changed

src/App.tsx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import Transfer from './pages/Transfer';
2626
global.Buffer = require('buffer').Buffer;
2727

2828
function App() {
29-
const { setProfiles, setMiningData, allRegions, setClosestRegion, setaAllNodes, setServerIpAddress, setServerPort, _vpnTimeUsedInMin, setActivePassportUpdated, setActivePassport, setRandomSolanaRPC, randomSolanaRPC } = useDaemonContext();
29+
const { setProfiles, setMiningData, allRegions, setClosestRegion, setaAllNodes, setServerIpAddress, setServerPort, _vpnTimeUsedInMin, setActivePassportUpdated, setActivePassport, setRandomSolanaRPC } = useDaemonContext();
3030
const setSOlanaRPC = (allNodes: nodes_info[]) => {
3131
const randomIndex = Math.floor(Math.random() * (allNodes.length - 1))
3232
setRandomSolanaRPC(allNodes[randomIndex])
@@ -69,15 +69,15 @@ function App() {
6969
}
7070

7171
const init = async () => {
72-
let vpnTimeUsedInMin = 0
73-
try {
74-
const ss = await localStorage.getItem("vpnTimeUsedInMin")
75-
if (ss) {
76-
vpnTimeUsedInMin = parseInt(ss)
77-
}
78-
} catch (ex) {
79-
80-
}
72+
let vpnTimeUsedInMin = 0
73+
try {
74+
const ss = await localStorage.getItem("vpnTimeUsedInMin")
75+
if (ss) {
76+
vpnTimeUsedInMin = parseInt(ss)
77+
}
78+
} catch (ex) {
79+
80+
}
8181
_vpnTimeUsedInMin.current = vpnTimeUsedInMin;
8282

8383
const queryParams = parseQueryParams(window.location.search);
@@ -124,7 +124,7 @@ function App() {
124124
console.log(ex)
125125
}
126126
};
127-
//@ts-ignore
127+
//@ts-ignore
128128
if (!window?.webkit && !window?.Android) {
129129
_getServerIpAddress();
130130
}

src/components/AccountList/ReferralProgram.tsx

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,16 @@
1-
import { useState } from 'react';
1+
import { useEffect, useState } from 'react';
22
import './index.css';
33
import Separator from '../Separator';
4-
import CopyAccountInfo from './CopyAccountInfo';
54
import { useDaemonContext } from '../../providers/DaemonProvider';
65
import Skeleton from '../Skeleton';
76

8-
import { ReactComponent as ConetToken } from './assets/conet-token.svg';
9-
import { ReactComponent as ConetEthToken } from './assets/conet-eth-token.svg';
10-
import { ReactComponent as SolanaToken } from './assets/solana-token.svg';
11-
import { ReactComponent as SpToken } from './assets/sp-token.svg';
12-
import PassportInfo from '../PassportInfo';
13-
import SelectActivePassportPopup from '../SelectActivePassportPopup';
14-
import { refreshSolanaBalances, storeSystemData } from '../../services/wallets';
15-
import { CoNET_Data } from '../../utils/globals';
16-
import { useNavigate } from 'react-router-dom';
177
import { ethers } from 'ethers';
188

199
import { ReactComponent as VisibilityOnIcon } from "./assets/visibility-on.svg";
2010
import { ReactComponent as VisibilityOffIcon } from "./assets/visibility-off.svg";
2111
import { getPassportTitle } from '../../utils/utils';
12+
import { currentPageInvitees, setCurrentPageInvitees } from '../../utils/globals';
13+
import { getRefereesPage } from '../../services/wallets';
2214

2315
const SP_EARNED_FROM_REFERRAL = 10
2416

@@ -28,6 +20,30 @@ export default function ReferralProgram() {
2820

2921
const [isAddressHidden, setIsAddressHidden] = useState(true);
3022
const [copied, setCopied] = useState(false);
23+
const [shouldRerender, setShouldRerender] = useState(false);
24+
25+
26+
const handlePreviousPage = async () => {
27+
if (currentPageInvitees > 0) {
28+
setCurrentPageInvitees(currentPageInvitees - 1)
29+
await getRefereesPage(profiles[0], currentPageInvitees)
30+
setShouldRerender(true)
31+
}
32+
}
33+
34+
const handleNextPage = async () => {
35+
if (currentPageInvitees < Math.ceil(profiles?.[0]?.spClub?.totalReferees / 100)) {
36+
setCurrentPageInvitees(currentPageInvitees + 1)
37+
await getRefereesPage(profiles[0], currentPageInvitees)
38+
setShouldRerender(true)
39+
}
40+
}
41+
42+
useEffect(() => {
43+
if (shouldRerender) {
44+
setShouldRerender(false)
45+
}
46+
}, [shouldRerender])
3147

3248
function handleCopy() {
3349
navigator.clipboard.writeText(profiles?.[0]?.keyID);
@@ -57,7 +73,7 @@ export default function ReferralProgram() {
5773
{profiles?.[0]?.keyID ?
5874
<>
5975
<div className="copy-text">
60-
<p>Wallet Address</p>
76+
<p>Copy this wallet address to invite your friends to Silent Pass</p>
6177
{
6278
isAddressHidden ?
6379
<div style={{ filter: 'blur(3px)' }}>
@@ -98,23 +114,24 @@ export default function ReferralProgram() {
98114
</div>
99115
<div style={{ marginLeft: '16px' }}>
100116
<div style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>
101-
<p>Referees</p>
117+
<p>Invitees</p>
102118
</div>
103119
<p>{profiles?.[0]?.spClub?.referees?.length}</p>
104120
</div>
105121
<div style={{ marginLeft: '16px' }}>
106122
<div style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>
107123
<p>$SP</p>
108124
</div>
109-
<p>{(Number(profiles?.[0]?.spClub?.totalReferees) * SP_EARNED_FROM_REFERRAL) || 0}</p>
125+
<p>0</p>
110126
</div>
111127
</div>
112128

113129
<Separator />
114130

115-
<div className="info-wrapper" style={{ maxHeight: '200px', overflowY: 'auto', }}>
131+
<div className="info-wrapper" style={{ display: 'flex', flexDirection: 'column', justifyContent: 'space-between', gap: '16px' }}>
116132
<p>Invitees</p>
117-
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '8px', width: '100%', paddingLeft: '16px' }}>
133+
134+
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '8px', width: '100%', paddingLeft: '16px', maxHeight: '100px', overflowY: 'auto', paddingRight: '10px' }}>
118135
{profiles?.[0]?.spClub
119136
?
120137
profiles?.[0].spClub?.totalReferees > 0 ?
@@ -127,6 +144,16 @@ export default function ReferralProgram() {
127144
<p>No invitees</p>
128145
: <Skeleton width={'100%'} height={'20px'} />}
129146
</div>
147+
148+
<div style={{ width: '100%', display: 'flex', flexDirection: 'row', alignItems: 'center', justifyContent: 'center', gap: '8px' }}>
149+
<div style={{ cursor: 'pointer' }} onClick={handlePreviousPage}>
150+
<img src="/assets/chevron-blue.svg" alt="Back" width={16} height={16} />
151+
</div>
152+
<div>{currentPageInvitees + 1} of {Math.ceil(profiles?.[0]?.spClub?.totalReferees / 100)}</div>
153+
<div style={{ cursor: 'pointer' }} onClick={handleNextPage}>
154+
<img src="/assets/chevron-blue.svg" alt="Back" width={16} height={16} style={{ transform: 'rotate(180deg)' }} />
155+
</div>
156+
</div>
130157
</div>
131158
</div>
132159
</div>

src/components/AccountList/index.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@
189189
align-items: center;
190190
padding: 16px;
191191
text-align: left;
192+
gap: 8px;
192193
}
193194

194195
.copy-div button {

src/components/SwapInput/index.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@
132132
align-items: center;
133133
padding: 16px;
134134
text-align: left;
135+
gap: 8px;
135136
}
136137

137138
.copy-div button {

src/providers/DaemonProvider.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ type DaemonContext = {
3838
setPurchasingPlan: (val: string) => void
3939
purchasingPlanPaymentTime: string
4040
setPurchasingPlanPaymentTime: (val: string) => void
41-
randomSolanaRPC: nodes_info|null
41+
randomSolanaRPC: nodes_info | null
4242
setRandomSolanaRPC: (val: nodes_info) => void;
4343
};
4444

@@ -115,7 +115,7 @@ export function DaemonProvider({ children }: DaemonProps) {
115115
const [activePassport, setActivePassport] = useState<any>(null);
116116
const [purchasingPlan, setPurchasingPlan] = useState<string>("premium");
117117
const [purchasingPlanPaymentTime, setPurchasingPlanPaymentTime] = useState<string>("monthly");
118-
const [randomSolanaRPC, setRandomSolanaRPC] = useState<nodes_info|null>(null);
118+
const [randomSolanaRPC, setRandomSolanaRPC] = useState<nodes_info | null>(null);
119119

120120
useEffect(() => {
121121
{
@@ -126,7 +126,7 @@ export function DaemonProvider({ children }: DaemonProps) {
126126

127127

128128
return (
129-
<Daemon.Provider value={{ power, setPower, sRegion, setSRegion, allRegions, setAllRegions, closestRegion, setClosestRegion, isRandom, setIsRandom, miningData, setMiningData, profiles, setProfiles, isMiningUp, setIsMiningUp, getAllNodes, setaAllNodes, serverIpAddress, setServerIpAddress, serverPort, setServerPort, serverPac, setServerPac, _vpnTimeUsedInMin, isPassportInfoPopupOpen, setIsPassportInfoPopupOpen, activePassportUpdated, setActivePassportUpdated, activePassport, setActivePassport, isSelectPassportPopupOpen, setIsSelectPassportPopupOpen, purchasingPlan, setPurchasingPlan, purchasingPlanPaymentTime, setPurchasingPlanPaymentTime, setRandomSolanaRPC, randomSolanaRPC}}>
129+
<Daemon.Provider value={{ power, setPower, sRegion, setSRegion, allRegions, setAllRegions, closestRegion, setClosestRegion, isRandom, setIsRandom, miningData, setMiningData, profiles, setProfiles, isMiningUp, setIsMiningUp, getAllNodes, setaAllNodes, serverIpAddress, setServerIpAddress, serverPort, setServerPort, serverPac, setServerPac, _vpnTimeUsedInMin, isPassportInfoPopupOpen, setIsPassportInfoPopupOpen, activePassportUpdated, setActivePassportUpdated, activePassport, setActivePassport, isSelectPassportPopupOpen, setIsSelectPassportPopupOpen, purchasingPlan, setPurchasingPlan, purchasingPlanPaymentTime, setPurchasingPlanPaymentTime, setRandomSolanaRPC, randomSolanaRPC }}>
130130
{children}
131131
</Daemon.Provider>
132132
);

src/services/listeners.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
} from "../utils/constants";
88
import {
99
CoNET_Data,
10+
currentPageInvitees,
1011
processingBlock,
1112
setCoNET_Data,
1213
setProcessingBlock,
@@ -49,7 +50,7 @@ const listenProfileVer = async (
4950
checkCurrentRate(setMiningData);
5051
await getProfileAssets(profiles[0], profiles[1]);
5152
await getVpnTimeUsed();
52-
await getSpClubInfo(profiles[0]);
53+
await getSpClubInfo(profiles[0], currentPageInvitees);
5354
}
5455

5556
if (block % 2 === 0) {

src/services/wallets.ts

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,7 @@ const refreshSolanaBalances = async (
744744
}
745745
};
746746

747-
const getSpClubInfo = async (profile: profile) => {
747+
const getSpClubInfo = async (profile: profile, currentPageInvitees: number) => {
748748
const temp = CoNET_Data;
749749

750750
if (!temp) {
@@ -788,7 +788,10 @@ const getSpClubInfo = async (profile: profile) => {
788788
}
789789

790790
try {
791-
const refereesResult = await contract.getReferees(profile.keyID, 0);
791+
const refereesResult = await contract.getReferees(
792+
profile.keyID,
793+
currentPageInvitees
794+
);
792795
profile.spClub.totalReferees = Number(refereesResult._total_length);
793796
profile.spClub.referees = [];
794797

@@ -832,6 +835,79 @@ const getSpClubInfo = async (profile: profile) => {
832835
setCoNET_Data(temp);
833836
};
834837

838+
const getRefereesPage = async (
839+
profile: profile,
840+
currentPageInvitees: number
841+
) => {
842+
const temp = CoNET_Data;
843+
844+
if (!temp) {
845+
return false;
846+
}
847+
848+
const wallet = new ethers.Wallet(profile.privateKeyArmor, conetDepinProvider);
849+
const contract = new ethers.Contract(
850+
contracts.SpClub.address,
851+
contracts.SpClub.abi,
852+
wallet
853+
);
854+
855+
if (!profile.spClub) {
856+
profile.spClub = {
857+
memberId: "0",
858+
referrer: "",
859+
referees: [],
860+
totalReferees: 0,
861+
};
862+
}
863+
864+
try {
865+
const refereesResult = await contract.getReferees(
866+
profile.keyID,
867+
currentPageInvitees
868+
);
869+
profile.spClub.totalReferees = Number(refereesResult._total_length);
870+
profile.spClub.referees = [];
871+
872+
if (
873+
refereesResult?.referees?.length > 0 &&
874+
refereesResult?.referees?.[0] ===
875+
"0x0000000000000000000000000000000000000000"
876+
)
877+
profile.spClub.totalReferees = 0;
878+
879+
const validReferees = refereesResult.referees.filter(
880+
(referee: string) =>
881+
referee !== "0x0000000000000000000000000000000000000000"
882+
);
883+
884+
// Use map to handle async operations
885+
const refereePromises = validReferees.map(async (referee: string) => {
886+
const _activePassport = await getCurrentPassportInfo(referee);
887+
888+
const activePassport = {
889+
nftID: _activePassport?.nftIDs?.toString(),
890+
expires: _activePassport?.expires?.toString(),
891+
expiresDays: _activePassport?.expiresDays?.toString(),
892+
premium: _activePassport?.premium,
893+
};
894+
895+
return {
896+
walletAddress: referee,
897+
activePassport: activePassport,
898+
};
899+
});
900+
901+
// Wait for all promises to resolve
902+
profile.spClub.referees = await Promise.all(refereePromises);
903+
} catch (error) {
904+
console.log(error);
905+
}
906+
907+
temp.profiles[0] = profile;
908+
setCoNET_Data(temp);
909+
};
910+
835911
const getSpClubMemberId = async (profile: profile) => {
836912
const wallet = new ethers.Wallet(profile.privateKeyArmor, conetDepinProvider);
837913
const contract = new ethers.Contract(
@@ -884,4 +960,5 @@ export {
884960
refreshSolanaBalances,
885961
getSpClubInfo,
886962
getSpClubMemberId,
963+
getRefereesPage,
887964
};

src/utils/globals.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
let CoNET_Data: encrypt_keys_object | null = null;
22
let processingBlock: boolean = false;
3+
let currentPageInvitees: number = 0;
34

45
const setCoNET_Data = (data: encrypt_keys_object | null) => {
56
CoNET_Data = data;
@@ -9,4 +10,15 @@ const setProcessingBlock = (value: boolean) => {
910
processingBlock = value;
1011
};
1112

12-
export { CoNET_Data, setCoNET_Data, processingBlock, setProcessingBlock };
13+
const setCurrentPageInvitees = (value: number) => {
14+
currentPageInvitees = value;
15+
};
16+
17+
export {
18+
CoNET_Data,
19+
setCoNET_Data,
20+
processingBlock,
21+
setProcessingBlock,
22+
currentPageInvitees,
23+
setCurrentPageInvitees,
24+
};

0 commit comments

Comments
 (0)