Skip to content

Commit

Permalink
finish copy referral code setup ui
Browse files Browse the repository at this point in the history
  • Loading branch information
peps committed Dec 27, 2024
1 parent a43ae71 commit b715902
Show file tree
Hide file tree
Showing 11 changed files with 262 additions and 96 deletions.
6 changes: 4 additions & 2 deletions public/locales/en/airdrop.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
"claimModalTitle": "EARN REWARDS FOR MINING ON TESTNET",
"claimReferralCode": "Claim your referral code <span>{{gems}}<image src='/assets/images/gem.png' alt=''/></span> gems.",
"claimReferralGifts": "Claim your referral code and earn {{gems}} gems. Once you connect your account, you’ll be awarded your gems.",
"claimSetlupText": "Earn gems while mining to increase your airdrop reward during testnet! Connect your airdrop account to start earning.",
"doLater": "I'll do this later",
"giftReferralCode": "Earn {{gems}} gems for each friend you invite to Tari Universe. Once they connect their account, you’ll be awarded your gems.",
"giftReferralCodeHeader": "Claim your referral code <span>{{gems}}<image src='/assets/images/gem.png' alt=''/></span> gems.",
Expand All @@ -36,5 +35,8 @@
"topTooltipTitle": "Testnet Rewards",
"unclaimedGems": "Unclaimed Gems",
"you-reached-your-giftinh-goal": "You reached your gifting goal!",
"your-friend-accepted-gift": "One of your friends accepted your gift!"
"your-friend-accepted-gift": "One of your friends accepted your gift!",
"setupLoginText": "Earn gems while mining to increase your airdrop reward during testnet! Connect your airdrop account to start earning.",
"setupInviteTitle": "invite friends & earn <span>{{gems}}</span> Gems",
"setupCopyButton": "Copy"
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ export const useAirdropAuth = () => {
);
}
},
[backendInMemoryConfig?.airdropTwitterAuthUrl, setAuthUuid]
// eslint-disable-next-line react-hooks/exhaustive-deps
[backendInMemoryConfig?.airdropTwitterAuthUrl]
);

const checkAuth = useCallback(() => {
Expand Down Expand Up @@ -54,7 +55,8 @@ export const useAirdropAuth = () => {
clearTimeout(timeout);
};
}
}, [authUuid, backendInMemoryConfig?.airdropApiUrl, restartMining, setAirdropTokens, setAuthUuid]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [authUuid, backendInMemoryConfig?.airdropApiUrl]);

return { handleAuth, checkAuth };
};
Original file line number Diff line number Diff line change
@@ -1,69 +1,21 @@
import { GIFT_GEMS, useAirdropStore } from '@app/store/useAirdropStore';
import { ClaimButton, GemPill, Image, Title, Wrapper } from './styles';
import { useCallback, useEffect, useState } from 'react';
import { open } from '@tauri-apps/plugin-shell';
import { v4 as uuidv4 } from 'uuid';
import { useEffect, useState } from 'react';
import ClaimModal from '../../components/ClaimModal/ClaimModal';
import { useTranslation } from 'react-i18next';
import gemImage from '../../images/gem.png';
import { useMiningStore } from '@app/store/useMiningStore';
import { useAirdropAuth } from '../../hooks/useAirdropAuth';

export default function LoggedOut() {
const [modalIsOpen, setModalIsOpen] = useState(false);
const { t } = useTranslation(['airdrop'], { useSuspense: false });
const restartMining = useMiningStore((s) => s.restartMining);
const { referralQuestPoints, authUuid, setAuthUuid, setAirdropTokens, setUserPoints, backendInMemoryConfig } =
useAirdropStore();
const { referralQuestPoints } = useAirdropStore();

const handleAuth = useCallback(
(code?: string) => {
const token = uuidv4();
if (backendInMemoryConfig?.airdropTwitterAuthUrl) {
setAuthUuid(token);
open(
`${backendInMemoryConfig?.airdropTwitterAuthUrl}?tauri=${token}${code ? `&universeReferral=${code}` : ''}`
);
}
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[backendInMemoryConfig?.airdropTwitterAuthUrl]
);
const { handleAuth, checkAuth } = useAirdropAuth();

useEffect(() => {
if (authUuid && backendInMemoryConfig?.airdropApiUrl) {
const interval = setInterval(() => {
if (authUuid) {
fetch(`${backendInMemoryConfig?.airdropApiUrl}/auth/twitter/get-token/${authUuid}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
})
.then((response) => response.json())
.then((data) => {
if (!data.error) {
clearInterval(interval);
setAirdropTokens(data);
restartMining();
}
});
}
}, 1000);
const timeout = setTimeout(
() => {
clearInterval(interval);
setAuthUuid('');
},
1000 * 60 * 5
);

return () => {
clearInterval(interval);
clearTimeout(timeout);
};
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [authUuid, backendInMemoryConfig?.airdropApiUrl]);
checkAuth();
}, [checkAuth]);

const gemsValue = (referralQuestPoints?.pointsForClaimingReferral || GIFT_GEMS).toLocaleString();

Expand Down
2 changes: 1 addition & 1 deletion src/containers/phase/Setup/Setup.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export const SetupWrapper = styled.div<{ $bg?: string }>`
position: fixed;
top: 0;
left: 0;
z-index: 1;
z-index: 3;
width: 100%;
height: 100%;
Expand Down
7 changes: 0 additions & 7 deletions src/containers/phase/Setup/Setup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,12 @@ import HeroText from './components/HeroText';
import InfoNav from './components/InfoNav/InfoNav';
import { SetupWrapper } from '@app/containers/phase/Setup/Setup.styles';
import grain from '/assets/img/grain.png';
import AirdropLogin from './components/AirdropLogin/AirdropLogin';
import { useAirdropStore } from '@app/store/useAirdropStore';
import AirdropShare from './components/AirdropShare/AirdropShare';

export default function Setup() {
useSetUp();

const { airdropTokens } = useAirdropStore();
const isLoggedIn = !!airdropTokens;

return (
<SetupWrapper $bg={grain}>
{isLoggedIn ? <AirdropShare /> : <AirdropLogin />}
<HeroText />
<InfoNav />
<Footer />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,18 @@ export default function AirdropLogin() {
checkAuth();
}, [checkAuth]);

const handleSubmit = useCallback(async () => {
await setAllowTelemetry(true);
return handleAuth();
}, [handleAuth, setAllowTelemetry]);
const handleSubmit = useCallback(
async (e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
e.stopPropagation();
await setAllowTelemetry(true);
return handleAuth();
},
[handleAuth, setAllowTelemetry]
);

return (
<Wrapper>
<Wrapper initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: 10 }}>
<GemsWrapper>
<Gem1 src={gemLargeImage} alt="" />
<Gem2 src={gemLargeImage} alt="" />
Expand All @@ -29,7 +34,7 @@ export default function AirdropLogin() {

<TextWrapper>
<Title>{t('claimModalTitle')}</Title>
<Text>{t('claimSetlupText')}</Text>
<Text>{t('setupLoginText')}</Text>
</TextWrapper>

<ClaimButton onClick={handleSubmit}>
Expand Down
10 changes: 8 additions & 2 deletions src/containers/phase/Setup/components/AirdropLogin/styles.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { m } from 'framer-motion';
import styled, { keyframes } from 'styled-components';

export const Wrapper = styled.div`
export const Wrapper = styled(m.div)`
position: fixed;
top: 47px;
right: 40px;
Expand Down Expand Up @@ -91,6 +92,11 @@ export const Title = styled('div')`
font-weight: 800;
line-height: 99.7%;
text-transform: uppercase;
max-width: 262px;
span {
color: #ff4a55;
}
`;

export const Text = styled('div')<{ $isError?: boolean }>`
Expand All @@ -100,7 +106,7 @@ export const Text = styled('div')<{ $isError?: boolean }>`
font-style: normal;
font-weight: 400;
line-height: 120.7%;
max-width: 468px;
max-width: 282px;
`;

export const ClaimButton = styled('button')`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { useCallback } from 'react';
import gemImage from './images/gem.png';
import { useTranslation } from 'react-i18next';
import { ToggleSwitch } from '@app/components/elements/ToggleSwitch';
import { useAppConfigStore } from '@app/store/useAppConfigStore';
import { BoxWrapper, Gem1, Gem2, Gem3, Gem4, Position, Text, TextWrapper, Title } from './styles';
import { BoxWrapper, Position, Text, TextWrapper, Title } from './styles';

export default function AirdropPermission() {
const allowTelemetry = useAppConfigStore((s) => s.allow_telemetry);
Expand All @@ -17,11 +16,6 @@ export default function AirdropPermission() {
return (
<Position initial={{ x: 100, opacity: 0 }} animate={{ x: 0, opacity: 1 }}>
<BoxWrapper>
<Gem1 src={gemImage} alt="" />
<Gem2 src={gemImage} alt="" />
<Gem3 src={gemImage} alt="" />
<Gem4 src={gemImage} alt="" />

<TextWrapper>
<Title>{t('permission.title')}</Title>
<Text>{t('permission.text')}</Text>
Expand Down
75 changes: 64 additions & 11 deletions src/containers/phase/Setup/components/AirdropShare/AirdropShare.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,81 @@
/* eslint-disable i18next/no-literal-string */
import { Gem1, Gem2, Gem3, GemsWrapper, Text, TextWrapper, Title } from '../AirdropLogin/styles';
import { Wrapper } from './styles';
import { useTranslation } from 'react-i18next';
import { GemsWrapper, Text, Title } from '../AirdropLogin/styles';
import { Avatar, Copied, CopyButton, CopyText, CopyWrapper, Gem1, Gem2, Gem3, TextWrapper, Wrapper } from './styles';
import { useTranslation, Trans } from 'react-i18next';
import gemLargeImage from '../../../../main/Airdrop/AirdropGiftTracker/images/gem.png';
import { REFERRAL_GEMS, useAirdropStore } from '@app/store/useAirdropStore';
import { useEffect, useState } from 'react';
import { useAirdropSyncState } from '@app/hooks/airdrop/useAirdropSyncState';
import { AnimatePresence, m } from 'framer-motion';

export default function AirdropShare() {
useAirdropSyncState();
const airdropUrl = useAirdropStore((state) => state.backendInMemoryConfig?.airdropUrl || '');
const { t } = useTranslation(['airdrop'], { useSuspense: false });
const { userDetails, referralQuestPoints } = useAirdropStore();

const profileimageurl = userDetails?.user?.profileimageurl;
const gems = (referralQuestPoints?.pointsForClaimingReferral || REFERRAL_GEMS).toLocaleString();

const referralCode = userDetails?.user?.referral_code || '';

const [copied, setCopied] = useState(false);

const url = `${airdropUrl}/download/${referralCode}`;

const handleCopy = () => {
setCopied(true);
navigator.clipboard.writeText(url);
};

useEffect(() => {
if (copied) {
const timeout = setTimeout(() => {
setCopied(false);
}, 2000);
return () => {
clearTimeout(timeout);
};
}
}, [copied]);

if (!userDetails) return null;

return (
<Wrapper>
<Wrapper initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: 10 }}>
<GemsWrapper>
<Gem1 src={gemLargeImage} alt="" />
<Gem2 src={gemLargeImage} alt="" />
<Gem3 src={gemLargeImage} alt="" />

<Avatar $image={profileimageurl || ''} />
</GemsWrapper>

<TextWrapper>
<Title>{t('claimModalTitle')}</Title>

<Text>
Earn gems while mining to increase your airdrop reward during testnet! Connect your airdrop account
to start earning.
</Text>
<Title>
<Trans
t={t}
i18nKey="setupInviteTitle"
ns="airdrop"
components={{ span: <span /> }}
values={{ gems }}
/>
</Title>
<Text>{t('setupLoginText')}</Text>
</TextWrapper>

<CopyWrapper onClick={handleCopy} $copied={copied}>
<AnimatePresence>
{copied && (
<Copied initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }}>
<m.span initial={{ y: '100%' }} animate={{ y: 0 }} exit={{ opacity: 0 }}>
{t('linkCopied')}
</m.span>
</Copied>
)}
</AnimatePresence>
<CopyText>{url}</CopyText>
<CopyButton>{t('setupCopyButton')}</CopyButton>
</CopyWrapper>
</Wrapper>
);
}
Loading

0 comments on commit b715902

Please sign in to comment.