Initial commit: Tapalka monorepo (bot, front, strapi)
This commit is contained in:
34
CMyTapper/robucks-front/components/friends/Friend.module.css
Normal file
34
CMyTapper/robucks-front/components/friends/Friend.module.css
Normal file
@@ -0,0 +1,34 @@
|
||||
.friend {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background: #FFFFFF0D;
|
||||
border-radius: 1rem;
|
||||
padding: 1rem;
|
||||
height: 74px;
|
||||
}
|
||||
|
||||
.friendContent {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.friendData {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.friendReferrals {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 3px;
|
||||
}
|
||||
|
||||
.friendBalance span {
|
||||
font-family: var(--font-manrope);
|
||||
font-weight: 600;
|
||||
font-size: 18px;
|
||||
line-height: 24px;
|
||||
color: white;
|
||||
}
|
||||
43
CMyTapper/robucks-front/components/friends/Friend.tsx
Normal file
43
CMyTapper/robucks-front/components/friends/Friend.tsx
Normal file
@@ -0,0 +1,43 @@
|
||||
'use client';
|
||||
import styles from '@/components/friends/Friend.module.css';
|
||||
import Image from 'next/image';
|
||||
import { IPlayer } from '@/interfaces/player.type';
|
||||
import { toFixed } from '@/utils/FormatNumber';
|
||||
|
||||
type Props = {
|
||||
player: IPlayer;
|
||||
};
|
||||
|
||||
const Friend = ({ player }: Props) => {
|
||||
return (
|
||||
<div className={styles.friend}>
|
||||
<div className={styles.friendContent}>
|
||||
<div className={styles.friendAvatar}>
|
||||
<Image
|
||||
src={'/icons/friend-icon.svg'}
|
||||
alt={'friend avatar'}
|
||||
height={42}
|
||||
width={42}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.friendData}>
|
||||
<span>{player?.attributes.telegram_nick}</span>
|
||||
<div className={styles.friendReferrals}>
|
||||
<Image
|
||||
src={'/icons/referrals-icon.svg'}
|
||||
alt={'referrals icon'}
|
||||
width={14}
|
||||
height={14}
|
||||
/>
|
||||
<span>{player?.attributes.my_referrals?.data?.length || 0}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.friendBalance}>
|
||||
<span>{toFixed(player?.attributes.balance)}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Friend;
|
||||
113
CMyTapper/robucks-front/components/friends/Friends.module.css
Normal file
113
CMyTapper/robucks-front/components/friends/Friends.module.css
Normal file
@@ -0,0 +1,113 @@
|
||||
.friends {
|
||||
background: #101010;
|
||||
height: 100vh;
|
||||
overflow-y: auto;
|
||||
padding-bottom: 90px;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.friendsTitle {
|
||||
align-items: flex-start;
|
||||
padding-top: 45px;
|
||||
padding-left: 1.5rem;
|
||||
font-weight: 600;
|
||||
font-size: 19px;
|
||||
color: white;
|
||||
line-height: 21px;
|
||||
font-family: var(--font-manrope);
|
||||
}
|
||||
|
||||
.inviteBlock {
|
||||
width: min(343px, 100%);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-top: 1rem;
|
||||
padding: 20px 16px;
|
||||
border-radius: 1.5rem;
|
||||
background: linear-gradient(81.19deg, rgba(66, 187, 71, 0.06) 0%, rgba(66, 187, 71, 0.2) 100%), #0E0E10;
|
||||
border: 1px solid #18181A;
|
||||
}
|
||||
|
||||
.rewardInvite {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row-reverse;
|
||||
gap: 3px;
|
||||
font-family: var(--font-clash);
|
||||
}
|
||||
|
||||
.rewardInvite span {
|
||||
font-size: 42px;
|
||||
font-weight: 600;
|
||||
line-height: 51px;
|
||||
background: linear-gradient(180deg, #42BB47 4.41%, #33A137 61.59%, #42BB47 101.32%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.inviteButtonBlock {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.inviteButtonBlock button {
|
||||
width: 100%;
|
||||
height: 46px;
|
||||
border-radius: 40px;
|
||||
color: white;
|
||||
background: #42BB47;
|
||||
border: none;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
line-height: 21px;
|
||||
font-family: var(--font-manrope);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.infoInvite {
|
||||
text-align: center;
|
||||
font-family: var(--font-manrope);
|
||||
}
|
||||
|
||||
.infoInvite span {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
line-height: 16px;
|
||||
color: #BBBBBB;
|
||||
}
|
||||
|
||||
.friendsList {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-top: 1rem;
|
||||
margin-top: 7px;
|
||||
gap: 5px;
|
||||
padding-bottom: 7px;
|
||||
}
|
||||
|
||||
.friendsListBlock {
|
||||
width: min(375px, 100%);
|
||||
margin-top: 2rem;
|
||||
background: #0E0E10;
|
||||
padding: 20px 16px;
|
||||
border: 1px solid #18181A;
|
||||
border-radius: 1.5rem;
|
||||
}
|
||||
|
||||
.friendsListHeader {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 19px;
|
||||
color: white;
|
||||
font-weight: 600;
|
||||
font-family: var(--font-manrope);
|
||||
line-height: 19px;
|
||||
}
|
||||
67
CMyTapper/robucks-front/components/friends/Friends.tsx
Normal file
67
CMyTapper/robucks-front/components/friends/Friends.tsx
Normal file
@@ -0,0 +1,67 @@
|
||||
'use client';
|
||||
import styles from '@/components/friends/Friends.module.css';
|
||||
import Image from 'next/image';
|
||||
import { FC } from 'react';
|
||||
import Friend from '@/components/friends/Friend';
|
||||
import CopyLinkToast from '@/components/ui/copy-link-toast/CopyLinkToast';
|
||||
import { usePlayerStore } from '@/store/player.state';
|
||||
|
||||
interface IFriends {
|
||||
isVisible: boolean;
|
||||
referral_fee: number | undefined;
|
||||
friendsAndReferralsCount: { friendsWord: string; referralWord: string };
|
||||
handleCopyInviteLink: () => Promise<void>;
|
||||
handleCloseToastLink: () => void;
|
||||
}
|
||||
|
||||
const Friends: FC<IFriends> = ({
|
||||
isVisible,
|
||||
referral_fee,
|
||||
friendsAndReferralsCount,
|
||||
handleCopyInviteLink,
|
||||
handleCloseToastLink,
|
||||
}) => {
|
||||
const { player } = usePlayerStore();
|
||||
const referrals = player?.attributes.my_referrals.data;
|
||||
|
||||
return (
|
||||
<div className={styles.friends}>
|
||||
<div className={styles.friendsTitle}>
|
||||
<span>Друзья</span>
|
||||
</div>
|
||||
<div className={styles.content}>
|
||||
<div className={styles.inviteBlock}>
|
||||
<div className={styles.rewardInvite}>
|
||||
<span>{referral_fee || 0}</span>
|
||||
<Image
|
||||
src={'/icons/robucks-icon.svg'}
|
||||
alt={'robucks icon'}
|
||||
width={32}
|
||||
height={32}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.inviteButtonBlock}>
|
||||
<button onClick={handleCopyInviteLink}>Пригласи друга</button>
|
||||
</div>
|
||||
<div className={styles.infoInvite}>
|
||||
<span>
|
||||
Получай 10% от твоих друзей +5% от друзей реферала +2.5% от их рефералов
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.friendsListBlock}>
|
||||
<div className={styles.friendsListHeader}>
|
||||
<span>{friendsAndReferralsCount.friendsWord}</span>
|
||||
<span>{friendsAndReferralsCount.referralWord}</span>
|
||||
</div>
|
||||
<div className={styles.friendsList}>
|
||||
{referrals?.map(referral => <Friend key={referral.id} player={referral} />)}
|
||||
</div>
|
||||
</div>
|
||||
<CopyLinkToast isVisible={isVisible} handleCloseToastLink={handleCloseToastLink} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Friends;
|
||||
@@ -0,0 +1,50 @@
|
||||
'use client';
|
||||
|
||||
import Friends from '@/components/friends/Friends';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { CalculateReferralsCount } from '@/utils/CalculateReferralsCount';
|
||||
import { updateFriendAndReferralCounts } from '@/utils/UpdateFriendAndReferralCount';
|
||||
import { usePlayerStore } from '@/store/player.state';
|
||||
|
||||
const FriendsContainer = ({ botLink }: { botLink: string }) => {
|
||||
const [isVisible, setIsVisible] = useState<boolean>(false);
|
||||
|
||||
const [userData, setUserData] = useState<{ id: number; username: string } | null>(null);
|
||||
|
||||
const { player } = usePlayerStore();
|
||||
|
||||
useEffect(() => {
|
||||
const initDataUnsafe = window.Telegram?.WebApp?.initDataUnsafe;
|
||||
if (!initDataUnsafe?.user) {
|
||||
return;
|
||||
}
|
||||
setUserData(initDataUnsafe.user);
|
||||
}, []);
|
||||
|
||||
const handleCopyInviteLink = useCallback(async () => {
|
||||
setIsVisible(true);
|
||||
setTimeout(() => {
|
||||
setIsVisible(false);
|
||||
}, 3000);
|
||||
return await navigator.clipboard.writeText(`${botLink}ref_${userData?.id}`);
|
||||
}, [userData, botLink]);
|
||||
|
||||
const handleCloseToastLink = useCallback(() => {
|
||||
setIsVisible(false);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Friends
|
||||
isVisible={isVisible}
|
||||
referral_fee={player?.attributes.referral_fee}
|
||||
friendsAndReferralsCount={updateFriendAndReferralCounts(
|
||||
player?.attributes.my_referrals?.data?.length || 0,
|
||||
CalculateReferralsCount(player),
|
||||
)}
|
||||
handleCopyInviteLink={handleCopyInviteLink}
|
||||
handleCloseToastLink={handleCloseToastLink}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default FriendsContainer;
|
||||
Reference in New Issue
Block a user