From 154b529245fe76e9dff0bfae1a65ea0e321fd59d Mon Sep 17 00:00:00 2001 From: camewell <130561684+camewell071@users.noreply.github.com> Date: Tue, 30 Jan 2024 18:22:14 +0700 Subject: [PATCH 01/50] chore: update code --- src/modules/PublicSale/activities/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/PublicSale/activities/index.tsx b/src/modules/PublicSale/activities/index.tsx index d309fe2b4..f98a7771d 100644 --- a/src/modules/PublicSale/activities/index.tsx +++ b/src/modules/PublicSale/activities/index.tsx @@ -256,7 +256,7 @@ Good luck and have fun! className={styles.itemWrapper_desc} dangerouslySetInnerHTML={{ __html: item.desc }} /> - {currentDay.diffDay === expandIndex && expandIndex === index && ( + {currentDay.diffDay === expandIndex && expandIndex === index && index === 1 && ( )} From dca035fe729fc23aa3728d9ef5001304915ddd07 Mon Sep 17 00:00:00 2001 From: wilfred Date: Tue, 30 Jan 2024 18:44:11 +0700 Subject: [PATCH 02/50] update --- src/modules/PublicSale/rewardButton/index.tsx | 21 ++++++++---- .../rewardButton/styles.module.scss | 26 +++++++++------ .../airdrop/StepAirdrop/Step/index.tsx | 2 +- src/modules/airdrop/StepAirdrop/index.tsx | 33 ++++++++++--------- 4 files changed, 48 insertions(+), 34 deletions(-) diff --git a/src/modules/PublicSale/rewardButton/index.tsx b/src/modules/PublicSale/rewardButton/index.tsx index 528a121f4..79729d33e 100644 --- a/src/modules/PublicSale/rewardButton/index.tsx +++ b/src/modules/PublicSale/rewardButton/index.tsx @@ -56,11 +56,7 @@ const RewardButton = ({ className }: any) => { return ( - +
{ - {'Top Leaderboard Reward'} + {'DAILY LEADERBOARD REWARDS'} { - 'Make contributions to climb to the top of the leaderboard and earn exciting rewards every day. Stay tuned for daily updates.' + 'The top 3 backers of each day will receive 10 Modular Inscriptions each.' } + + window.open( + 'https://twitter.com/punk3700/status/1752291478901235915', + '_blank', + ) + } + className={s.link} + > + {'Learn more >'} + diff --git a/src/modules/PublicSale/rewardButton/styles.module.scss b/src/modules/PublicSale/rewardButton/styles.module.scss index 481efa7a3..a6ea5b09f 100644 --- a/src/modules/PublicSale/rewardButton/styles.module.scss +++ b/src/modules/PublicSale/rewardButton/styles.module.scss @@ -1,5 +1,4 @@ .container { - display: flex; align-items: center; gap: 8px; @@ -7,15 +6,15 @@ position: relative; padding: 4px; padding-right: 14px !important; - border: 1px solid #FFFFFF1A; - background-color: #FFFFFF1A; + border: 1px solid #ffffff1a; + background-color: #ffffff1a; cursor: pointer; width: 100%; .icon { width: 40px; height: 40px; - background: url("/public-sale/rwbn.png"); + background: url('/public-sale/rwbn.png'); background-size: cover; background-repeat: no-repeat; cursor: pointer; @@ -58,10 +57,10 @@ } .menuContent { - border: 1px solid #FFFFFF26; + border: 1px solid #ffffff26; padding: 20px; background: linear-gradient(180deg, #282828 0%, #131313 146.93%), - linear-gradient(0deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.2)) !important; + linear-gradient(0deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.2)) !important; min-width: 300px; border-radius: 0 !important; @@ -86,8 +85,15 @@ margin-top: 8px; } + .link { + margin-top: 10px; + font-size: 12px; + color: #fa4e0e; + cursor: pointer; + } + .learnMoreWrapper { - background: #FFFFFF; + background: #ffffff; padding: 6px 6px 6px 16px; width: fit-content; color: #000000; @@ -110,18 +116,18 @@ &:first-child { color: #ffffff; - background: #FFFFFF12; + background: #ffffff12; } &:last-child { color: #000000; - background: #FFFFFF; + background: #ffffff; } } } .raffleBg { - background: url("/public-sale/raffle_frame.svg"); + background: url('/public-sale/raffle_frame.svg'); background-size: contain; background-repeat: no-repeat; padding: 8px; diff --git a/src/modules/airdrop/StepAirdrop/Step/index.tsx b/src/modules/airdrop/StepAirdrop/Step/index.tsx index 09067120d..0ebf867dc 100644 --- a/src/modules/airdrop/StepAirdrop/Step/index.tsx +++ b/src/modules/airdrop/StepAirdrop/Step/index.tsx @@ -73,7 +73,7 @@ export default function ItemCommunity({ onClickTweetToClaim: (airdropType: AirdropStep) => void; }) { console.log('content', content); - + const [isEnd, setIsEnd] = React.useState( dayjs .utc(content?.expiredTime, 'YYYY-MM-DD HH:mm:ss') diff --git a/src/modules/airdrop/StepAirdrop/index.tsx b/src/modules/airdrop/StepAirdrop/index.tsx index c60354f92..49494d650 100644 --- a/src/modules/airdrop/StepAirdrop/index.tsx +++ b/src/modules/airdrop/StepAirdrop/index.tsx @@ -25,6 +25,7 @@ import React, { useEffect, useMemo, useRef, useState } from 'react'; import { useDispatch } from 'react-redux'; import ItemStep, { AirdropStep, AirdropType, IItemCommunity } from './Step'; import s from './styles.module.scss'; +import { compareString } from '@/utils/string'; export const getMessageEVM = (address: string) => { return `Verify you are the owner of the wallet ${address}`; @@ -144,23 +145,23 @@ const StepsAirdrop = (props: IProps) => { try { const { address } = await signMessage(getMessageEVM); - const resGMHolders = await getBVMAirdrop({ address: address }); - AirdropStorage.setIsConnectMetaMask(true); - AirdropStorage.setAirdropGMHolders(resGMHolders); - - // if ( - // type === AirdropStep.generativeUsers || - // type === AirdropStep.perceptronsHolders - // ) { - // const resp = await getGenerativeProfile(address); + const resGMHolders = await getBVMAirdrop({ + address: address, + }); - // if (resp && resp.data && resp.data?.walletAddressBtcTaproot) { - // const resGenerativeUsers = await getBVMAirdrop({ - // address: resp.data?.walletAddressBtcTaproot, - // }); - // AirdropStorage.setAirdropGenerativeUsers(resGenerativeUsers); - // } - // } + AirdropStorage.setIsConnectMetaMask(true); + if (compareString(type, AirdropStep.generativeUsers)) { + AirdropStorage.setAirdropGenerativeUsers(JSON.stringify(resGMHolders)); + } else if (compareString(type, AirdropStep.perceptronsHolders)) { + AirdropStorage.setAirdropPerceptronsHolders( + JSON.stringify(resGMHolders), + ); + } else { + AirdropStorage.setAirdropGMHolders(JSON.stringify(resGMHolders)); + } + setTimeout(() => { + window.location.reload(); + }, 1000); } catch (error) { console.log('error', error); } From a4247de2c122e9d0b04fe2c608675a97ff38cb93 Mon Sep 17 00:00:00 2001 From: wilfred Date: Tue, 30 Jan 2024 18:46:43 +0700 Subject: [PATCH 03/50] hiden --- src/modules/airdrop/StepAirdrop/Step/index.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/modules/airdrop/StepAirdrop/Step/index.tsx b/src/modules/airdrop/StepAirdrop/Step/index.tsx index 0ebf867dc..6279d327b 100644 --- a/src/modules/airdrop/StepAirdrop/Step/index.tsx +++ b/src/modules/airdrop/StepAirdrop/Step/index.tsx @@ -295,12 +295,12 @@ export default function ItemCommunity({ 'MMM D, YYYY', )} - + */} ) : ( isConnectMetaMask && ( @@ -322,14 +322,14 @@ export default function ItemCommunity({ 'MMM D, YYYY', )} - + */} ) : ( isConnectMetaMask && ( @@ -352,14 +352,14 @@ export default function ItemCommunity({ 'MMM D, YYYY', )} - + */} ) : ( (isConnectMetaMask || isConnectBitcoinWallet) && ( From 775007c02ef5eedc8333a1fc0a35b43de39cf197 Mon Sep 17 00:00:00 2001 From: wilfred Date: Tue, 30 Jan 2024 18:54:35 +0700 Subject: [PATCH 04/50] update --- src/modules/PublicSale/BuyForm/index.tsx | 17 ++++++++++++++++- .../PublicSale/depositModal/deposit.content.tsx | 10 +++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/modules/PublicSale/BuyForm/index.tsx b/src/modules/PublicSale/BuyForm/index.tsx index 667f913e6..5f66d79d6 100644 --- a/src/modules/PublicSale/BuyForm/index.tsx +++ b/src/modules/PublicSale/BuyForm/index.tsx @@ -217,7 +217,7 @@ const PrivateSaleForm = ({ vcInfo }: { vcInfo?: VCInfo }) => { {/* : '-'}{' '}*/} {/* BVM*/} {/**/} - {Boolean(userContributeInfo?.view_boost) && ( + {Boolean(userContributeInfo?.view_boost) ? ( { : '-'} + ) : ( + + + + + )}
diff --git a/src/modules/PublicSale/depositModal/deposit.content.tsx b/src/modules/PublicSale/depositModal/deposit.content.tsx index 38c7bff40..bf5919b6f 100644 --- a/src/modules/PublicSale/depositModal/deposit.content.tsx +++ b/src/modules/PublicSale/depositModal/deposit.content.tsx @@ -184,11 +184,11 @@ const DepositContent: React.FC = ({ return ( - {/*{hasStaked && ( - - Buy and stake your $BVM to earn rewards from the BVM ecosystem and our collaborative Bitcoin L2s and dApps partners. Your $BVM will be automatically staked after the public sale, and you can choose to unstake at any time. - - )}*/} + + Make a contribution using any of the currencies below.
After your + payment processes, you’ll get a confirmation code to claim your $BVM + allocation later. +
{/* {secretCode && ( <> From 930c96ce3948c681fb38cf2222c99ab89b293ceb Mon Sep 17 00:00:00 2001 From: 0xmegalodon Date: Tue, 30 Jan 2024 19:09:54 +0700 Subject: [PATCH 05/50] add tooltip & login --- public/icons/ic-tooltip.svg | 3 + src/components/InfoTooltip/IcHelp.tsx | 9 + src/components/InfoTooltip/index.tsx | 105 ++++++++++++ src/components/InfoTooltip/style.module.scss | 3 + src/modules/PublicSale/BuyForm/index.tsx | 61 ++++--- .../PublicSale/BuyForm/styles.module.scss | 13 ++ .../PublicSale/depositModal/login.tooltip.tsx | 162 ++++++++++++++++++ .../depositModal/styles.module.scss | 16 ++ .../steps/VerifyTwModal/styles.module.scss | 8 + 9 files changed, 354 insertions(+), 26 deletions(-) create mode 100644 public/icons/ic-tooltip.svg create mode 100644 src/components/InfoTooltip/IcHelp.tsx create mode 100644 src/components/InfoTooltip/index.tsx create mode 100644 src/components/InfoTooltip/style.module.scss create mode 100644 src/modules/PublicSale/depositModal/login.tooltip.tsx diff --git a/public/icons/ic-tooltip.svg b/public/icons/ic-tooltip.svg new file mode 100644 index 000000000..8beadc29c --- /dev/null +++ b/public/icons/ic-tooltip.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/InfoTooltip/IcHelp.tsx b/src/components/InfoTooltip/IcHelp.tsx new file mode 100644 index 000000000..8377575b1 --- /dev/null +++ b/src/components/InfoTooltip/IcHelp.tsx @@ -0,0 +1,9 @@ +/* eslint-disable jsx-a11y/alt-text */ +import { Image } from '@chakra-ui/react'; +import React from 'react'; + +const IcHelp = () => { + return ; +}; + +export default IcHelp; diff --git a/src/components/InfoTooltip/index.tsx b/src/components/InfoTooltip/index.tsx new file mode 100644 index 000000000..4fd7553cc --- /dev/null +++ b/src/components/InfoTooltip/index.tsx @@ -0,0 +1,105 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { + Box, + Flex, + PlacementWithLogical, + Popover, + PopoverArrow, + PopoverBody, + PopoverContent, + PopoverTrigger, + Text, + useDisclosure, +} from '@chakra-ui/react'; +import { ReactNode, useEffect, useRef } from 'react'; +import IcHelp from './IcHelp'; + +interface InfoTooltipProps { + label: ReactNode; + children?: ReactNode; + placement?: PlacementWithLogical; + iconSize?: string; + fontSize?: string; + iconColor?: string; + showIcon?: boolean; + iconName?: any; + setIsOpen?: (b: boolean) => void; + isStyleConfig?: boolean; + bodyClassName?: any; + className?: any; +} + +const InfoTooltip = (props: InfoTooltipProps) => { + const { + label, + children, + showIcon = false, + setIsOpen, + isStyleConfig = true, + bodyClassName, + className + } = props; + const { isOpen, onToggle, onClose } = useDisclosure(); + + useEffect(() => { + setIsOpen && setIsOpen(isOpen); + }, [isOpen]); + + const initRef = useRef(); + + const renderChild = () => { + if (children && showIcon) { + return ( + + {children} + + + ); + } + if (children) { + return children; + } + return ; + }; + + return ( + + + { + e.preventDefault(); + e.stopPropagation(); + onToggle(); + }} + className={className} + > + {renderChild()} + + + + + + {label} + + + + ); +}; + +export default InfoTooltip; diff --git a/src/components/InfoTooltip/style.module.scss b/src/components/InfoTooltip/style.module.scss new file mode 100644 index 000000000..3eb0bd5b6 --- /dev/null +++ b/src/components/InfoTooltip/style.module.scss @@ -0,0 +1,3 @@ +.popover { + color: red; +} \ No newline at end of file diff --git a/src/modules/PublicSale/BuyForm/index.tsx b/src/modules/PublicSale/BuyForm/index.tsx index bfafd9cf3..f05fd2311 100644 --- a/src/modules/PublicSale/BuyForm/index.tsx +++ b/src/modules/PublicSale/BuyForm/index.tsx @@ -1,17 +1,13 @@ import { Box, Button, Flex, Text, Tooltip } from '@chakra-ui/react'; import { FormikProps, useFormik } from 'formik'; -import React, { forwardRef, useEffect, useMemo, useRef, useState } from 'react'; +import React, { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import s from './styles.module.scss'; import { getPublicSaleLeaderBoards, getPublicSaleSummary, postPublicsaleWalletInfoManualCheck, } from '@/services/public-sale'; -import { - defaultSummary, - IPublicSaleDepositInfo, - VCInfo, -} from '@/interfaces/vc'; +import { defaultSummary, IPublicSaleDepositInfo, VCInfo } from '@/interfaces/vc'; import { formatCurrency } from '@/utils/format'; import { toast } from 'react-hot-toast'; import dayjs from 'dayjs'; @@ -26,6 +22,8 @@ import cx from 'classnames'; import AuthenStorage from '@/utils/storage/authen.storage'; import { PUBLIC_SALE_END } from '@/modules/Whitelist'; import NumberScale from '@/components/NumberScale'; +import { getLink } from '@/utils/helpers'; +import LoginTooltip from '@/modules/PublicSale/depositModal/login.tooltip'; interface FormValues { tokenAmount: string; @@ -167,16 +165,19 @@ const PrivateSaleForm = ({ vcInfo }: { vcInfo?: VCInfo }) => { {...rest} cursor={token ? 'pointer' : 'auto'} > - - Your contribution - + { + + }}/> + {token @@ -250,6 +251,28 @@ const PrivateSaleForm = ({ vcInfo }: { vcInfo?: VCInfo }) => { ); }); + const renderLoginTooltip = useCallback(() => { + return ( + token ? ( + } + > + + + ) : ( + + ) + ) + }, [token]); + return (
@@ -356,23 +379,9 @@ const PrivateSaleForm = ({ vcInfo }: { vcInfo?: VCInfo }) => { {/*)}*/}
- {token ? ( - } - > - - - ) : ( - - )} + { + renderLoginTooltip() + }
diff --git a/src/modules/PublicSale/BuyForm/styles.module.scss b/src/modules/PublicSale/BuyForm/styles.module.scss index 83f85e20e..c67529d10 100644 --- a/src/modules/PublicSale/BuyForm/styles.module.scss +++ b/src/modules/PublicSale/BuyForm/styles.module.scss @@ -200,6 +200,19 @@ .backer { cursor: pointer; } + + :global { + .chakra-popover__popper { + z-index: 999999; + + .chakra-popover__content { + &:focus-visible { + outline: none !important; + box-shadow: 0px 0px 24px -6px #0000001F !important; + } + } + } + } } .grid { diff --git a/src/modules/PublicSale/depositModal/login.tooltip.tsx b/src/modules/PublicSale/depositModal/login.tooltip.tsx new file mode 100644 index 000000000..8a30c6a2f --- /dev/null +++ b/src/modules/PublicSale/depositModal/login.tooltip.tsx @@ -0,0 +1,162 @@ +import { Flex, Text } from '@chakra-ui/react'; +import React, { useEffect, useRef, useState } from 'react'; +import s from './styles.module.scss'; +import { useAppSelector } from '@/stores/hooks'; +import AuthenStorage from '@/utils/storage/authen.storage'; +import { IAuthenCode } from '@/modules/Whitelist/steps'; +import { generateTokenWithTwPost, requestAuthenByShareCode } from '@/services/player-share'; +import { getPublicSaleSummary } from '@/services/public-sale'; +import { setBearerToken } from '@/services/whitelist'; +import { requestReload } from '@/stores/states/common/reducer'; +import { userSelector } from '@/stores/states/user/selector'; +import { getLink } from '@/utils/helpers'; +import { useDispatch } from 'react-redux'; +import { formatCurrency } from '@/utils/format'; +import InfoTooltip from '@/components/InfoTooltip'; +import VerifyTwModal from '@/modules/Whitelist/steps/VerifyTwModal'; + +const LoginTooltip = ({ onClose }: { onClose: any }) => { + const user = useAppSelector(userSelector); + const token = AuthenStorage.getAuthenKey() || AuthenStorage.getGuestAuthenKey(); + const [authenCode, setAuthenCode] = useState(); + const timer = useRef(); + const [submitting, setSubmitting] = useState(false); + const dispatch = useDispatch(); + const [showManualCheck, setShowManualCheck] = useState(false); + const [showManualCheckModal, setShowManualCheckModal] = useState(false); + + useEffect(() => { + if (authenCode?.public_code) { + setSubmitting(true); + timer.current = setInterval(async () => { + handleVerifyTwitter(); + }, 5000); + } + return () => { + clearInterval(timer.current); + }; + }, [authenCode?.public_code]); + + useEffect(() => { + if(token) { + setShowManualCheckModal(false); + } + }, [token]); + + const handleVerifyTwitter = async (): Promise => { + try { + const result = await generateTokenWithTwPost( + authenCode?.secret_code as string, + ); + onVerifyTwSuccess(result); + } catch (err) { + console.log('handleVerifyTwitter', err); + } + }; + + const onVerifyTwSuccess = (result: any) => { + if (result) { + clearInterval(timer.current); + const twitterToken = AuthenStorage.getAuthenKey(); + if (!twitterToken || twitterToken !== result?.token) { + AuthenStorage.setAuthenKey(result?.token); + setBearerToken(result?.token); + } + setSubmitting(false); + dispatch(requestReload()); + onClose(); + } + }; + + const generateLinkTweet = async () => { + let code = ''; + if (!token) { + const res: any = await requestAuthenByShareCode(); + setAuthenCode(res); + code = `\n\n#${res?.public_code}`; + } + + const shareUrl = !user?.referral_code ? 'bvm.network/public-sale' : getLink(user?.referral_code || ''); + + const saleSummary = await getPublicSaleSummary(); + const content = `Welcome to the future of Bitcoin!\n\n@BVMnetwork is the first modular blockchain metaprotocol that lets you launch your Bitcoin L2 blockchain in a few clicks.\n\nJoin the ${formatCurrency( + saleSummary.total_user || '0', + 0, + 0, + 'BTC', + false, + )} early contributors backing us with ${formatCurrency( + saleSummary.total_usdt_value || '0', + 0, + 0, + 'BTC', + false, + )} to build the future of Bitcoin.${code}`; + return `https://twitter.com/intent/tweet?url=${shareUrl}&text=${encodeURIComponent( + content, + )}`; + // + // if (token) { + // + // } else { + // const content = `Welcome to the future of Bitcoin with @BVMnetwork\n\nBitcoin Virtual Machine is the first modular blockchain metaprotocol that lets you launch your Bitcoin L2 blockchain protocol in a few clicks\n\n$BVM public sale starting soon${code}\n\nJoin the allowlist`; + // return `https://twitter.com/intent/tweet?url=${shareUrl}&text=${encodeURIComponent( + // content, + // )}`; + // } + + }; + + const handleShareTw = async () => { + const content = await generateLinkTweet(); + window.open(content, '_blank'); + + setTimeout(() => { + setShowManualCheck(true); + }, 10000); + }; + + return ( + <> + { + !token && + Sign in to X and claim your boost! + {showManualCheck && ( + setShowManualCheckModal(true)} + mt={1} + fontSize={'14px !important'} + > + Can't link account? + + )} +
+ } + className={s.loginTooltip} + bodyClassName={s.toolTipModal} + /> + } + { + setShowManualCheckModal(false); + }} + secretCode={authenCode?.secret_code} + onSuccess={onVerifyTwSuccess} + title={`Can't link account?`} + /> + + ); +}; + +export default LoginTooltip; diff --git a/src/modules/PublicSale/depositModal/styles.module.scss b/src/modules/PublicSale/depositModal/styles.module.scss index 129e50a2c..23206ff6d 100644 --- a/src/modules/PublicSale/depositModal/styles.module.scss +++ b/src/modules/PublicSale/depositModal/styles.module.scss @@ -283,3 +283,19 @@ } } } + +.toolTipModal { + background: #FFFFFF; + box-shadow: 0px 0px 24px -6px #0000001F !important; + border-radius: 4px; + padding: 16px !important; + outline: none !important; + color: black; +} + +.loginTooltip { + background: #fa4e0e; + border-radius: 100px; + width: fit-content; +} + diff --git a/src/modules/Whitelist/steps/VerifyTwModal/styles.module.scss b/src/modules/Whitelist/steps/VerifyTwModal/styles.module.scss index 7aebefee4..82e38d483 100644 --- a/src/modules/Whitelist/steps/VerifyTwModal/styles.module.scss +++ b/src/modules/Whitelist/steps/VerifyTwModal/styles.module.scss @@ -136,6 +136,14 @@ .modalManualHeader { padding-bottom: 0 !important; + + :global { + svg { + path { + fill: black; + } + } + } } .modalContent { From f807096b5ac8e0a1f6cf49f319d80ef2cf004e27 Mon Sep 17 00:00:00 2001 From: 0xmegalodon Date: Tue, 30 Jan 2024 19:10:46 +0700 Subject: [PATCH 06/50] add tooltip & login --- src/modules/PublicSale/BuyForm/index.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/modules/PublicSale/BuyForm/index.tsx b/src/modules/PublicSale/BuyForm/index.tsx index 256cbd960..9c84592f5 100644 --- a/src/modules/PublicSale/BuyForm/index.tsx +++ b/src/modules/PublicSale/BuyForm/index.tsx @@ -22,10 +22,7 @@ import cx from 'classnames'; import AuthenStorage from '@/utils/storage/authen.storage'; import { PUBLIC_SALE_END } from '@/modules/Whitelist'; import NumberScale from '@/components/NumberScale'; -import DepositGuestCodeHere, { - GuestCodeHere, -} from '../depositModal/deposit.guest.code'; -import { getLink } from '@/utils/helpers'; +import { GuestCodeHere } from '../depositModal/deposit.guest.code'; import LoginTooltip from '@/modules/PublicSale/depositModal/login.tooltip'; interface FormValues { From 6e97fe16ae277c43f39a15d60a10be11fc49b08d Mon Sep 17 00:00:00 2001 From: 0xmegalodon Date: Tue, 30 Jan 2024 19:15:49 +0700 Subject: [PATCH 07/50] add tooltip & login --- src/modules/PublicSale/BuyForm/index.tsx | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/src/modules/PublicSale/BuyForm/index.tsx b/src/modules/PublicSale/BuyForm/index.tsx index 9c84592f5..9bed64287 100644 --- a/src/modules/PublicSale/BuyForm/index.tsx +++ b/src/modules/PublicSale/BuyForm/index.tsx @@ -216,7 +216,7 @@ const PrivateSaleForm = ({ vcInfo }: { vcInfo?: VCInfo }) => { {/* : '-'}{' '}*/} {/* BVM*/} {/**/} - {Boolean(userContributeInfo?.view_boost) ? ( + {Boolean(userContributeInfo?.view_boost) && ( { : '-'} - ) : ( - - - - - - )} + ) + }
From 8e88ce944ce14566a75c39f7a97c4fa3505f140a Mon Sep 17 00:00:00 2001 From: 0xmegalodon Date: Tue, 30 Jan 2024 20:39:23 +0700 Subject: [PATCH 08/50] add tooltip & login --- src/modules/PublicSale/raffleButton/styles.module.scss | 2 +- src/modules/PublicSale/rewardButton/styles.module.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/PublicSale/raffleButton/styles.module.scss b/src/modules/PublicSale/raffleButton/styles.module.scss index 75554d227..338f300e7 100644 --- a/src/modules/PublicSale/raffleButton/styles.module.scss +++ b/src/modules/PublicSale/raffleButton/styles.module.scss @@ -68,7 +68,7 @@ } @include is-mobile { - min-width: 95vw; + min-width: 85vw; } .title { diff --git a/src/modules/PublicSale/rewardButton/styles.module.scss b/src/modules/PublicSale/rewardButton/styles.module.scss index a6ea5b09f..ef26d97ca 100644 --- a/src/modules/PublicSale/rewardButton/styles.module.scss +++ b/src/modules/PublicSale/rewardButton/styles.module.scss @@ -69,7 +69,7 @@ } @include is-mobile { - min-width: 95vw; + min-width: 85vw; } .title { From b1021ade127b372cec3531ff09924630c7cebc86 Mon Sep 17 00:00:00 2001 From: 0xmegalodon Date: Tue, 30 Jan 2024 20:43:45 +0700 Subject: [PATCH 09/50] add tooltip & login --- src/components/InfoTooltip/index.tsx | 7 +++++-- src/modules/PublicSale/depositModal/login.tooltip.tsx | 4 +++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/components/InfoTooltip/index.tsx b/src/components/InfoTooltip/index.tsx index 4fd7553cc..f9224c148 100644 --- a/src/components/InfoTooltip/index.tsx +++ b/src/components/InfoTooltip/index.tsx @@ -70,7 +70,11 @@ const InfoTooltip = (props: InfoTooltipProps) => { isOpen={isOpen} onClose={onClose} styleConfig={ - { zIndex: 999999999 } + isStyleConfig + ? { + zIndex: 999999999, + } + : undefined } > @@ -91,7 +95,6 @@ const InfoTooltip = (props: InfoTooltipProps) => { diff --git a/src/modules/PublicSale/depositModal/login.tooltip.tsx b/src/modules/PublicSale/depositModal/login.tooltip.tsx index 8a30c6a2f..bac552b4d 100644 --- a/src/modules/PublicSale/depositModal/login.tooltip.tsx +++ b/src/modules/PublicSale/depositModal/login.tooltip.tsx @@ -109,7 +109,9 @@ const LoginTooltip = ({ onClose }: { onClose: any }) => { const handleShareTw = async () => { const content = await generateLinkTweet(); - window.open(content, '_blank'); + setTimeout(() => { + window.open(content, '_blank'); + }, 500); setTimeout(() => { setShowManualCheck(true); From cdb9cbec1942e6a9284c6e518c9174e7f00bede3 Mon Sep 17 00:00:00 2001 From: 0xmegalodon Date: Tue, 30 Jan 2024 21:05:55 +0700 Subject: [PATCH 10/50] add tooltip & login --- src/modules/PublicSale/BuyForm/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/PublicSale/BuyForm/index.tsx b/src/modules/PublicSale/BuyForm/index.tsx index 9bed64287..352557ad5 100644 --- a/src/modules/PublicSale/BuyForm/index.tsx +++ b/src/modules/PublicSale/BuyForm/index.tsx @@ -272,7 +272,7 @@ const PrivateSaleForm = ({ vcInfo }: { vcInfo?: VCInfo }) => { ) ) - }, [token]); + }, [token, userContributeInfo]); return (
From e2ac38a7b4faef3e262b81074c090e86ff295600 Mon Sep 17 00:00:00 2001 From: 0xmegalodon Date: Wed, 31 Jan 2024 07:14:10 +0700 Subject: [PATCH 11/50] add tooltip & login --- src/modules/PublicSale/BuyForm/index.tsx | 5 ++++- src/modules/PublicSale/leaderBoardVisual/index.tsx | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/modules/PublicSale/BuyForm/index.tsx b/src/modules/PublicSale/BuyForm/index.tsx index 352557ad5..f76487d04 100644 --- a/src/modules/PublicSale/BuyForm/index.tsx +++ b/src/modules/PublicSale/BuyForm/index.tsx @@ -24,6 +24,8 @@ import { PUBLIC_SALE_END } from '@/modules/Whitelist'; import NumberScale from '@/components/NumberScale'; import { GuestCodeHere } from '../depositModal/deposit.guest.code'; import LoginTooltip from '@/modules/PublicSale/depositModal/login.tooltip'; +import { useAppSelector } from '@/stores/hooks'; +import { commonSelector } from '@/stores/states/common/selector'; interface FormValues { tokenAmount: string; @@ -83,6 +85,7 @@ const PrivateSaleForm = ({ vcInfo }: { vcInfo?: VCInfo }) => { }, []); const timeIntervalSummary = useRef(undefined); + const { needReload } = useAppSelector(commonSelector); useEffect(() => { getContributeInfo(); @@ -97,7 +100,7 @@ const PrivateSaleForm = ({ vcInfo }: { vcInfo?: VCInfo }) => { return () => { clearInterval(timeIntervalSummary.current); }; - }, [token]); + }, [token, needReload]); const getContributeInfo = async () => { const res = await getPublicSaleSummary(); diff --git a/src/modules/PublicSale/leaderBoardVisual/index.tsx b/src/modules/PublicSale/leaderBoardVisual/index.tsx index 23caa2e2e..52c8d41fa 100644 --- a/src/modules/PublicSale/leaderBoardVisual/index.tsx +++ b/src/modules/PublicSale/leaderBoardVisual/index.tsx @@ -13,7 +13,7 @@ import AvatarItem from '@/modules/PublicSale/leaderBoardVisual/AvatarItem'; import AnimatedText from '@/modules/PublicSale/leaderBoardVisual/FloatTexts'; import { useSelector } from 'react-redux'; import { LEADER_BOARD_MODE } from '@/modules/PublicSale/leaderBoardSwitch'; -import { setAnimatedLatestContributors, setNeedCheckDeposit } from '@/stores/states/common/reducer'; +import { requestReload, setAnimatedLatestContributors, setNeedCheckDeposit } from '@/stores/states/common/reducer'; import AuthenStorage from '@/utils/storage/authen.storage'; import useWindowSize from '@/hooks/useWindowSize'; @@ -141,6 +141,7 @@ const LeaderBoardVisual = (props: IProps) => { if (newRes?.length > 0) { latestContributors.current = [...newRes].concat(latestContributors.current); + dispatch(requestReload()); } animatedLatestContributors.current = newRes || []; dispatch(setAnimatedLatestContributors(newRes || [])); From 2b2af582db7f352f1f5b7a8ee659e0860fe7e12c Mon Sep 17 00:00:00 2001 From: camewell <130561684+camewell071@users.noreply.github.com> Date: Wed, 31 Jan 2024 09:44:38 +0700 Subject: [PATCH 12/50] chore: update ui --- package.json | 1 + .../activities/components/NakaCountDown.tsx | 6 ++--- .../components/TradeNakaWinnersPopup.tsx | 25 ++++++++++++------- src/modules/PublicSale/activities/index.tsx | 7 +++--- yarn.lock | 12 +++++++++ 5 files changed, 36 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 327afd114..f1b98166a 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "react-final-form": "^6.5.9", "react-google-recaptcha-v3": "^1.10.1", "react-hot-toast": "^2.4.1", + "react-jazzicon": "^1.0.4", "react-modal-video": "^2.0.1", "react-player": "^2.14.1", "react-qr-code": "^2.0.12", diff --git a/src/modules/PublicSale/activities/components/NakaCountDown.tsx b/src/modules/PublicSale/activities/components/NakaCountDown.tsx index cf94c9b79..148102757 100644 --- a/src/modules/PublicSale/activities/components/NakaCountDown.tsx +++ b/src/modules/PublicSale/activities/components/NakaCountDown.tsx @@ -28,13 +28,13 @@ const NakaCountDown = React.memo(() => { {!!bestPNL?.winner ? ( - Top PNL + Top 1 PNL { if (!bestPNL?.winner?.twitter_username) return; window.open(`https://twitter.com/${bestPNL?.winner?.twitter_username}`, '_blank'); }}> - {formatString(bestPNL?.winner?.twitter_name || bestPNL?.winner?.address , 6)} +{formatCurrency(bestPNL?.winner?.realized_pnl || '0', 0, 5, 'TC', false)} BTC + {formatString(bestPNL?.winner?.twitter_name || bestPNL?.winner?.address , 6)} +{formatCurrency(bestPNL?.winner?.realized_pnl || '0', 0, 5)} BTC ) : ( @@ -49,7 +49,7 @@ const NakaCountDown = React.memo(() => { )} - Rewards + Reward ${bestPNL.reward} diff --git a/src/modules/PublicSale/activities/components/TradeNakaWinnersPopup.tsx b/src/modules/PublicSale/activities/components/TradeNakaWinnersPopup.tsx index 0e0521084..7cddc0aee 100644 --- a/src/modules/PublicSale/activities/components/TradeNakaWinnersPopup.tsx +++ b/src/modules/PublicSale/activities/components/TradeNakaWinnersPopup.tsx @@ -15,6 +15,7 @@ import { useAppSelector } from '@/stores/hooks'; import { coinPricesSelector } from '@/stores/states/common/selector'; import { Coin } from '@/stores/states/common/types'; import BigNumber from 'bignumber.js'; +import Jazzicon, { jsNumberForAddress } from 'react-jazzicon'; interface IProps extends IBaseModalProps { } @@ -47,6 +48,7 @@ const TradeNakaWinnersPopup = ({ isShow, onHide }: IProps) => { config, label: USER, render(row: TopWinner) { + const name = row?.twitter_name || row?.twitter_username; return ( { }} maxW="170px" > - + {!!name ? ( + + ) : ( + + )} + {row?.twitter_username ? formatName(row?.twitter_username || '-', 17) : (row?.address || '').slice(0, 8)} ); diff --git a/src/modules/PublicSale/activities/index.tsx b/src/modules/PublicSale/activities/index.tsx index f98a7771d..c0b052b00 100644 --- a/src/modules/PublicSale/activities/index.tsx +++ b/src/modules/PublicSale/activities/index.tsx @@ -69,15 +69,16 @@ Good luck and have fun! link: 'https://nakachain.xyz/app', }, { - title: 'View winners', + title: 'Winners', type: 'action', onPress: () => { onOpenNakaWinners() } }, ], - desc: 'Experience on-chain BRC-20 perpetual trading with Naka Chain - the Bitcoin L2 for BRC-20 DeFi powered by BVM' + - '
For the first time, you can go long and short on BRC-20 tokens on a decentralized platform', + desc: 'NakaChain is a low-cost and lightning-fast Bitcoin Layer 2 blockchain designed for DeFi apps, enabling the payment of gas fees in Bitcoin. It’s powered by BVM with these modules: Bitcoin for security, Polygon for data availability, and Optimism for execution.' + + '

On the second day of awesomeness, challenge yourself to dominate the market by trading futures on BRC-20 tokens\' prices. The top gainer will be rewarded every hour.' + + '

Total rewards: $3,000', }, { key: 2, diff --git a/yarn.lock b/yarn.lock index 26b3005b9..108fc0f1a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6455,6 +6455,11 @@ merge2@^1.3.0, merge2@^1.4.1: resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== +mersenne-twister@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mersenne-twister/-/mersenne-twister-1.1.0.tgz#f916618ee43d7179efcf641bec4531eb9670978a" + integrity sha512-mUYWsMKNrm4lfygPkL3OfGzOPTR2DBlTkBNHM//F6hGp8cLThY897crAlk3/Jo17LEOOjQUrNAx6DvgO77QJkA== + micro-ftch@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/micro-ftch/-/micro-ftch-0.3.1.tgz#6cb83388de4c1f279a034fb0cf96dfc050853c5f" @@ -7161,6 +7166,13 @@ react-is@^16.13.1, react-is@^16.7.0: resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +react-jazzicon@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/react-jazzicon/-/react-jazzicon-1.0.4.tgz#31e5f6908e042786ba93a9093b852dea1870e7a0" + integrity sha512-/3kWv5vtAhI18GBFoqjpxRTtL+EImuB73PAC02r/zJQ6E+PAUmoBx8edYvTCIYHwS01uFf6N3elTDqSrVPwg4w== + dependencies: + mersenne-twister "^1.1.0" + react-modal-video@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/react-modal-video/-/react-modal-video-2.0.1.tgz#ede12736b306316d33d969cd9a8c826c49e23354" From 0eed19263e2770a9a63e421fe3854a5ea40cc11a Mon Sep 17 00:00:00 2001 From: camewell <130561684+camewell071@users.noreply.github.com> Date: Wed, 31 Jan 2024 09:57:06 +0700 Subject: [PATCH 13/50] chore: allow toggle --- src/modules/PublicSale/activities/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/PublicSale/activities/index.tsx b/src/modules/PublicSale/activities/index.tsx index c0b052b00..b3623a14b 100644 --- a/src/modules/PublicSale/activities/index.tsx +++ b/src/modules/PublicSale/activities/index.tsx @@ -281,7 +281,7 @@ Good luck and have fun!

7 days of awesomeness. Experience Bitcoin like never before.

- { + { setExpandIndex(expandedIndex as number) }}> {DAYS.map(renderItem)} From 497db3f3802a6d086e7ecc599b154f0c4868e8f8 Mon Sep 17 00:00:00 2001 From: camewell <130561684+camewell071@users.noreply.github.com> Date: Wed, 31 Jan 2024 10:07:11 +0700 Subject: [PATCH 14/50] chore: update ui --- src/modules/PublicSale/activities/index.tsx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/modules/PublicSale/activities/index.tsx b/src/modules/PublicSale/activities/index.tsx index b3623a14b..f6ee7366a 100644 --- a/src/modules/PublicSale/activities/index.tsx +++ b/src/modules/PublicSale/activities/index.tsx @@ -147,11 +147,12 @@ Good luck and have fun! }, [isOpenNakaWinners]); const currentDay = React.useMemo(() => { - const diffDay = new BigNumber( - dayjs.utc(PUBLIC_SALE_START).diff(dayjs.utc(), 'days'), - ) - .absoluteValue() - .toNumber(); + // const diffDay = new BigNumber( + // dayjs.utc(PUBLIC_SALE_START).diff(dayjs.utc(), 'days'), + // ) + // .absoluteValue() + // .toNumber(); + const diffDay = 0; return { step: DAYS.length > diffDay ? DAYS[diffDay] : DAYS[DAYS.length - 1], diffDay, @@ -218,7 +219,7 @@ Good luck and have fun! return ( currentDay.diffDay} + isDisabled={isDisable} className={styles.itemWrapper} > {({ isExpanded }) => ( From ef53fb3582ccfd2caa1222a2be82d1af281f23df Mon Sep 17 00:00:00 2001 From: wilfred Date: Wed, 31 Jan 2024 10:20:42 +0700 Subject: [PATCH 15/50] fixed airdrop --- src/Providers/StoreProvider/index.tsx | 13 +- src/modules/airdrop/Section_2/index.tsx | 119 ----------- .../airdrop/StepAirdrop/Step/index.tsx | 185 ++++++++---------- src/modules/airdrop/StepAirdrop/index.tsx | 44 +++-- src/stores/index.ts | 2 +- src/stores/reducer.ts | 4 +- src/stores/states/airdrop/reducer.ts | 32 +++ src/stores/states/airdrop/types.ts | 12 ++ 8 files changed, 170 insertions(+), 241 deletions(-) create mode 100644 src/stores/states/airdrop/reducer.ts create mode 100644 src/stores/states/airdrop/types.ts diff --git a/src/Providers/StoreProvider/index.tsx b/src/Providers/StoreProvider/index.tsx index fe0742f79..eb3f58eff 100644 --- a/src/Providers/StoreProvider/index.tsx +++ b/src/Providers/StoreProvider/index.tsx @@ -1,8 +1,11 @@ 'use client'; -import { AppStore, store } from '@/stores'; +import AppLoading from '@/components/AppLoading'; +import { AppStore, persistor, store } from '@/stores'; +import { Center } from '@chakra-ui/react'; import React, { useRef } from 'react'; import { Provider } from 'react-redux'; +import { PersistGate } from 'redux-persist/integration/react'; // import useBootstrapApp from '@/hooks/useBootstrapApp'; @@ -18,5 +21,11 @@ export default function StoreProvider({ storeRef.current = store; } - return {children}; + return ( + + } persistor={persistor}> + {children} + + + ); } diff --git a/src/modules/airdrop/Section_2/index.tsx b/src/modules/airdrop/Section_2/index.tsx index 3a075bcd6..c09fd55b5 100644 --- a/src/modules/airdrop/Section_2/index.tsx +++ b/src/modules/airdrop/Section_2/index.tsx @@ -105,125 +105,6 @@ const Section_2 = () => { } }; - const renderItem = (item: IContent, index: number) => { - return ( - - {/* Date */} - - {item.dateStr} - - - {/* Content */} - - {/* ThumbImg */} - - - {/* Right - Content */} - - - {item.twitterLink && ( - - - - {item.appName} - - - )} - - - - - {item.linkShortName} - - - - - - - {item.title} - - - - {item.desc} - - - - - - - - - - ); - }; - return ( void; + loading?: boolean; } export default function ItemCommunity({ @@ -66,14 +66,14 @@ export default function ItemCommunity({ content, isLoading, onClickTweetToClaim, + loading, }: { index: number; content: IItemCommunity; isLoading?: boolean; onClickTweetToClaim: (airdropType: AirdropStep) => void; + loading?: boolean; }) { - console.log('content', content); - const [isEnd, setIsEnd] = React.useState( dayjs .utc(content?.expiredTime, 'YYYY-MM-DD HH:mm:ss') @@ -81,13 +81,13 @@ export default function ItemCommunity({ ); const { isActive, image, isDisable = false, step } = content; const airdropAlphaUsers = useSelector(airdropAlphaUsersSelector); - const airdropGMHolders = AirdropStorage.getAirdropGMHolders(); - const airdropGenerativeUsers = AirdropStorage.getAirdropGenerativeUsers(); - const airdropPerceptronsHolders = - AirdropStorage.getAirdropPerceptronsHolders(); const user = useAppSelector(userSelector); - const isConnectMetaMask = AirdropStorage.getIsConnectMetaMask(); - const isConnectBitcoinWallet = AirdropStorage.getIsConnectBitcoinWallet(); + + const airdrops = useSelector(airdropSelector).airdrops; + + const airdropContent = useMemo(() => { + return airdrops.find((v) => compareString(v.type, content.step)); + }, [airdrops, content]); const isRunning = useMemo(() => { return isActive; @@ -190,7 +190,7 @@ export default function ItemCommunity({ */} - + {airdropContent && !loading ? ( + <> + {airdropContent?.balance ? ( + + + Airdrop: {formatCurrency(airdropContent?.balance)}{' '} + $BVM - Vesting at:{' '} + {dayjs(airdropContent?.claimeable_at).format( + 'MMM D, YYYY', + )} + + + ) : ( + + Your wallet do not have airdrop + + )} + ) : ( - isConnectMetaMask && ( - - Your wallet do not have airdrop - - ) + <> )} )} {content?.step === AirdropStep.generativeUsers && ( <> - {airdropGenerativeUsers ? ( - - - Airdrop: {formatCurrency(airdropGenerativeUsers?.balance)}{' '} - $BVM - Vesting at:{' '} - {dayjs(airdropGenerativeUsers?.claimeable_at).format( - 'MMM D, YYYY', - )} - - {/* */} - + {airdropContent && !loading ? ( + <> + {airdropContent?.balance ? ( + + + Airdrop: {formatCurrency(airdropContent?.balance)}{' '} + $BVM - Vesting at:{' '} + {dayjs(airdropContent?.claimeable_at).format( + 'MMM D, YYYY', + )} + + + ) : ( + + Your wallet do not have airdrop + + )} + ) : ( - isConnectMetaMask && ( - - Your wallet do not have airdrop - - ) + <> )} )} {content?.step === AirdropStep.perceptronsHolders && ( <> - {airdropPerceptronsHolders ? ( - - - Airdrop:{' '} - {formatCurrency(airdropPerceptronsHolders?.balance)} $BVM - - Vesting at:{' '} - {dayjs(airdropPerceptronsHolders?.claimeable_at).format( - 'MMM D, YYYY', - )} - - {/* */} - + {airdropContent && !loading ? ( + <> + {airdropContent?.balance ? ( + + + Airdrop: {formatCurrency(airdropContent?.balance)}{' '} + $BVM - Vesting at:{' '} + {dayjs(airdropContent?.claimeable_at).format( + 'MMM D, YYYY', + )} + + + ) : ( + + Your wallet do not have airdrop + + )} + ) : ( - (isConnectMetaMask || isConnectBitcoinWallet) && ( - - Your wallet do not have airdrop - - ) + <> )} )} diff --git a/src/modules/airdrop/StepAirdrop/index.tsx b/src/modules/airdrop/StepAirdrop/index.tsx index 49494d650..a80640244 100644 --- a/src/modules/airdrop/StepAirdrop/index.tsx +++ b/src/modules/airdrop/StepAirdrop/index.tsx @@ -22,10 +22,11 @@ import AllowListStorage from '@/utils/storage/allowlist.storage'; import AuthenStorage from '@/utils/storage/authen.storage'; import { Flex } from '@chakra-ui/react'; import React, { useEffect, useMemo, useRef, useState } from 'react'; -import { useDispatch } from 'react-redux'; +import { useDispatch, useSelector } from 'react-redux'; import ItemStep, { AirdropStep, AirdropType, IItemCommunity } from './Step'; import s from './styles.module.scss'; import { compareString } from '@/utils/string'; +import { airdropSelector, setAirdrop } from '@/stores/states/airdrop/reducer'; export const getMessageEVM = (address: string) => { return `Verify you are the owner of the wallet ${address}`; @@ -49,6 +50,9 @@ const StepsAirdrop = (props: IProps) => { const [authenCode, setAuthenCode] = useState(); const [showManualCheck, setShowManualCheck] = useState(false); const [showConnectModal, setShowConnectModal] = useState(false); + const airdrops = useSelector(airdropSelector).airdrops; + const [loading, setLoading] = useState(false); + const [currentStep, setCurrentStep] = useState(-1); useEffect(() => { if (token) { @@ -143,27 +147,34 @@ const StepsAirdrop = (props: IProps) => { const handleVerifyWallet = async (type?: AirdropStep) => { try { + setCurrentStep(type); const { address } = await signMessage(getMessageEVM); + let currentAirdropContent = { type }; + + const airdropContent = airdrops.find((v) => compareString(v.type, type)); + + if (!airdropContent) { + dispatch(setAirdrop(currentAirdropContent)); + } + + setLoading(true); + const resGMHolders = await getBVMAirdrop({ - address: address, + address: '0xd558Ce757d610ea33fFeA371693e48df8eFC292E', }); - AirdropStorage.setIsConnectMetaMask(true); - if (compareString(type, AirdropStep.generativeUsers)) { - AirdropStorage.setAirdropGenerativeUsers(JSON.stringify(resGMHolders)); - } else if (compareString(type, AirdropStep.perceptronsHolders)) { - AirdropStorage.setAirdropPerceptronsHolders( - JSON.stringify(resGMHolders), - ); - } else { - AirdropStorage.setAirdropGMHolders(JSON.stringify(resGMHolders)); + if (resGMHolders && compareString(resGMHolders.type, type)) { + currentAirdropContent = { + ...currentAirdropContent, + ...resGMHolders, + }; + dispatch(setAirdrop(currentAirdropContent)); } - setTimeout(() => { - window.location.reload(); - }, 1000); } catch (error) { console.log('error', error); + } finally { + setLoading(false); } }; @@ -222,7 +233,7 @@ const StepsAirdrop = (props: IProps) => { `, actionText: 'Connect your Metamask', image: '/airdrop/gm.png', - actionHandle: handleVerifyWallet, + actionHandle: () => handleVerifyWallet(AirdropStep.gmHolders), isActive: true, isDisable: true, right: { @@ -259,7 +270,7 @@ const StepsAirdrop = (props: IProps) => { handleShowManualPopup: handleShowManualPopup, }, ]; - }, [token, needReload, raffleCode]); + }, [token, needReload, raffleCode, loading, currentStep]); return ( { content={item} isLoading={item.step === AirdropStep.alphaUsers && submitting} onClickTweetToClaim={handleTweetToClaim} + loading={loading && compareString(currentStep, item.step)} /> ); })} diff --git a/src/stores/index.ts b/src/stores/index.ts index 1b8803ffd..afee6af6e 100644 --- a/src/stores/index.ts +++ b/src/stores/index.ts @@ -10,7 +10,7 @@ const reducers = combineReducers(reducer); const persistConfig = getPersistConfig({ key: 'root', storage: persistLocalStorage, - whitelist: ['liquidity', 'futures', 'common.poolTabIndex', 'common.coinPrices'], + whitelist: ['common.poolTabIndex', 'common.coinPrices', 'airdrop'], rootReducer: reducers, }); diff --git a/src/stores/reducer.ts b/src/stores/reducer.ts index ac6065844..255b40754 100644 --- a/src/stores/reducer.ts +++ b/src/stores/reducer.ts @@ -3,10 +3,12 @@ import common from '@/stores/states/common/reducer'; import modal from '@/stores/states/modal/reducer'; import user from '@/stores/states/user/reducer'; import activities from '@/stores/states/activities/reducer'; +import airdrop from '@/stores/states/airdrop/reducer'; export default { common, modal, user, - activities + activities, + airdrop, }; diff --git a/src/stores/states/airdrop/reducer.ts b/src/stores/states/airdrop/reducer.ts new file mode 100644 index 000000000..7a199ac5b --- /dev/null +++ b/src/stores/states/airdrop/reducer.ts @@ -0,0 +1,32 @@ +import { createSlice } from '@reduxjs/toolkit'; +import { CommonState } from './types'; +import { RootState } from '@/stores'; +import { compareString } from '@/utils/string'; + +const initialState: CommonState = { + airdrops: [], +}; + +const slice = createSlice({ + name: 'airdrop', + initialState, + reducers: { + setAirdrop: (state, actions) => { + const airdrop = state.airdrops.findIndex((v) => + compareString(v.type, actions.payload?.type), + ); + + if (airdrop >= 0) { + state.airdrops[airdrop] = actions.payload; + } else { + state.airdrops = [...state.airdrops, actions.payload]; + } + }, + }, +}); + +export const { setAirdrop } = slice.actions; + +export const airdropSelector = (state: RootState) => state.airdrop; + +export default slice.reducer; diff --git a/src/stores/states/airdrop/types.ts b/src/stores/states/airdrop/types.ts new file mode 100644 index 000000000..f81d43c0f --- /dev/null +++ b/src/stores/states/airdrop/types.ts @@ -0,0 +1,12 @@ +interface IAirdrop { + id?: number; + address?: string; + balance?: string; + type?: number; + claimed?: boolean; + claimeable_at?: Date; +} + +export interface CommonState { + airdrops: IAirdrop[]; +} From d9af3fe1856a4aaa3c676e0197f2f79d8e9d3a69 Mon Sep 17 00:00:00 2001 From: wilfred Date: Wed, 31 Jan 2024 10:23:54 +0700 Subject: [PATCH 16/50] update --- src/modules/airdrop/StepAirdrop/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/airdrop/StepAirdrop/index.tsx b/src/modules/airdrop/StepAirdrop/index.tsx index a80640244..721463fb7 100644 --- a/src/modules/airdrop/StepAirdrop/index.tsx +++ b/src/modules/airdrop/StepAirdrop/index.tsx @@ -161,7 +161,7 @@ const StepsAirdrop = (props: IProps) => { setLoading(true); const resGMHolders = await getBVMAirdrop({ - address: '0xd558Ce757d610ea33fFeA371693e48df8eFC292E', + address, }); if (resGMHolders && compareString(resGMHolders.type, type)) { From 367a2ef2e5993f68b88d727245c34680202118e4 Mon Sep 17 00:00:00 2001 From: camewell <130561684+camewell071@users.noreply.github.com> Date: Wed, 31 Jan 2024 10:42:02 +0700 Subject: [PATCH 17/50] chore: update code --- .../activities/hooks/useTradeNakaData.tsx | 2 -- src/modules/PublicSale/activities/index.tsx | 19 ++++++++++++------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/modules/PublicSale/activities/hooks/useTradeNakaData.tsx b/src/modules/PublicSale/activities/hooks/useTradeNakaData.tsx index 08aae315f..7c7e043a7 100644 --- a/src/modules/PublicSale/activities/hooks/useTradeNakaData.tsx +++ b/src/modules/PublicSale/activities/hooks/useTradeNakaData.tsx @@ -4,8 +4,6 @@ import { daySecondSelector } from '@/stores/states/activities/selector'; const useTradeNakaData = () => { const { topWinners, bestPNL } = useAppSelector(daySecondSelector); - console.log('SANG TEST: ', bestPNL); - return { topWinners, bestPNL diff --git a/src/modules/PublicSale/activities/index.tsx b/src/modules/PublicSale/activities/index.tsx index f6ee7366a..bdb20e56c 100644 --- a/src/modules/PublicSale/activities/index.tsx +++ b/src/modules/PublicSale/activities/index.tsx @@ -77,7 +77,7 @@ Good luck and have fun! }, ], desc: 'NakaChain is a low-cost and lightning-fast Bitcoin Layer 2 blockchain designed for DeFi apps, enabling the payment of gas fees in Bitcoin. It’s powered by BVM with these modules: Bitcoin for security, Polygon for data availability, and Optimism for execution.' + - '

On the second day of awesomeness, challenge yourself to dominate the market by trading futures on BRC-20 tokens\' prices. The top gainer will be rewarded every hour.' + + '

On the second day of awesomeness, challenge yourself to dominate the market by trading futures on BRC-20 tokens\' prices. The top gainer will be rewarded every 2 hours.' + '

Total rewards: $3,000', }, { @@ -147,12 +147,17 @@ Good luck and have fun! }, [isOpenNakaWinners]); const currentDay = React.useMemo(() => { - // const diffDay = new BigNumber( - // dayjs.utc(PUBLIC_SALE_START).diff(dayjs.utc(), 'days'), - // ) - // .absoluteValue() - // .toNumber(); - const diffDay = 0; + let diffDay = new BigNumber( + dayjs.utc(PUBLIC_SALE_START).diff(dayjs.utc(), 'days'), + ) + .absoluteValue() + .toNumber(); + + // Case naka start at 4h UTC + if (diffDay === 1 && dayjs.utc().hour() < 4) { + diffDay = 0; + } + return { step: DAYS.length > diffDay ? DAYS[diffDay] : DAYS[DAYS.length - 1], diffDay, From d63598bb89b7c6dfe7cc3a881db60e1d468f2ec3 Mon Sep 17 00:00:00 2001 From: 0xmegalodon Date: Wed, 31 Jan 2024 10:48:43 +0700 Subject: [PATCH 18/50] add tooltip & login --- src/modules/PublicSale/leaderBoardVisual/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/PublicSale/leaderBoardVisual/index.tsx b/src/modules/PublicSale/leaderBoardVisual/index.tsx index 52c8d41fa..50ba1d250 100644 --- a/src/modules/PublicSale/leaderBoardVisual/index.tsx +++ b/src/modules/PublicSale/leaderBoardVisual/index.tsx @@ -89,7 +89,7 @@ const LeaderBoardVisual = (props: IProps) => { const fnLoadData = leaderBoardMode === LEADER_BOARD_MODE.DAY ? getPublicSaleTop : getPublicSaleLeaderBoards; const getLimit = () => { - const limitMobile = mobileScreen ? (TOTALs - 1) : TOTALs; + const limitMobile = mobileScreen ? (TOTALs - 2) : TOTALs; return leaderBoardMode === LEADER_BOARD_MODE.DAY ? limitMobile : token ? (TOTALs - 1) : limitMobile; }; @@ -178,7 +178,7 @@ const LeaderBoardVisual = (props: IProps) => { return tmp; }); - setListRender(tmsss.slice(0, mobileScreen ? (TOTALs - 1) : TOTALs)); + setListRender(tmsss.slice(0, mobileScreen ? (TOTALs - 2) : TOTALs)); setListMissingRender(missingArray); }, [list, mobileScreen]); From 04f567bc4c883adde93f0a8db8141329fd121666 Mon Sep 17 00:00:00 2001 From: wilfred Date: Wed, 31 Jan 2024 10:56:07 +0700 Subject: [PATCH 19/50] update --- src/modules/PublicSale/raffleButton/index.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/modules/PublicSale/raffleButton/index.tsx b/src/modules/PublicSale/raffleButton/index.tsx index 597830b47..530158c8a 100644 --- a/src/modules/PublicSale/raffleButton/index.tsx +++ b/src/modules/PublicSale/raffleButton/index.tsx @@ -337,8 +337,14 @@ const RaffleButton = ({ className }: any) => { alignItems={'center'} fontWeight={'500'} > - Floor price: - {programeInfo?.reward} + {Boolean(programeInfo?.reward) && ( + <> + + Floor price:{' '} + + {programeInfo?.reward} + + )}
From 394972fe267338485ac4a67aaa596d583146f270 Mon Sep 17 00:00:00 2001 From: camewell <130561684+camewell071@users.noreply.github.com> Date: Wed, 31 Jan 2024 11:02:15 +0700 Subject: [PATCH 20/50] chore: update ui --- src/modules/PublicSale/activities/components/NakaCountDown.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/PublicSale/activities/components/NakaCountDown.tsx b/src/modules/PublicSale/activities/components/NakaCountDown.tsx index 148102757..1f361b39a 100644 --- a/src/modules/PublicSale/activities/components/NakaCountDown.tsx +++ b/src/modules/PublicSale/activities/components/NakaCountDown.tsx @@ -22,7 +22,7 @@ const NakaCountDown = React.memo(() => { - +
{!!bestPNL?.winner ? ( From c5d0488634597a9ff8df21a46e8949e2d9afe813 Mon Sep 17 00:00:00 2001 From: camewell <130561684+camewell071@users.noreply.github.com> Date: Wed, 31 Jan 2024 11:05:04 +0700 Subject: [PATCH 21/50] chore: update code --- src/modules/PublicSale/activities/components/NakaCountDown.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/PublicSale/activities/components/NakaCountDown.tsx b/src/modules/PublicSale/activities/components/NakaCountDown.tsx index 1f361b39a..0d0df62cd 100644 --- a/src/modules/PublicSale/activities/components/NakaCountDown.tsx +++ b/src/modules/PublicSale/activities/components/NakaCountDown.tsx @@ -40,7 +40,7 @@ const NakaCountDown = React.memo(() => { ) : ( - Top PNL + Top 1 PNL Be the first!!! From 7db0d7f0080f47df1f3f4909478a145b1beef940 Mon Sep 17 00:00:00 2001 From: wilfred Date: Wed, 31 Jan 2024 11:09:42 +0700 Subject: [PATCH 22/50] update --- src/modules/PublicSale/raffleButton/index.tsx | 22 ++++++++++++++----- .../raffleButton/styles.module.scss | 2 +- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/modules/PublicSale/raffleButton/index.tsx b/src/modules/PublicSale/raffleButton/index.tsx index 530158c8a..ebd28b289 100644 --- a/src/modules/PublicSale/raffleButton/index.tsx +++ b/src/modules/PublicSale/raffleButton/index.tsx @@ -136,18 +136,25 @@ const RaffleButton = ({ className }: any) => { Share more post to increase
your winning chance
- - - Share now - + { + + Share now + ) : ( diff --git a/src/modules/PublicSale/raffleButton/styles.module.scss b/src/modules/PublicSale/raffleButton/styles.module.scss index 338f300e7..d6b458c78 100644 --- a/src/modules/PublicSale/raffleButton/styles.module.scss +++ b/src/modules/PublicSale/raffleButton/styles.module.scss @@ -148,7 +148,7 @@ .learnMoreWrapper { background: #ffffff; - padding: 4px 6px 4px 16px; + padding: 4px; width: fit-content; color: #000000; font-size: 14px; From aa6529eaf0e8f8baf87c6f4d4bccf9d81ca3793c Mon Sep 17 00:00:00 2001 From: 0xmegalodon Date: Wed, 31 Jan 2024 11:10:41 +0700 Subject: [PATCH 23/50] add tooltip & login --- src/modules/PublicSale/BuyForm/index.tsx | 6 +++--- src/modules/PublicSale/BuyForm/styles.module.scss | 9 +++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/modules/PublicSale/BuyForm/index.tsx b/src/modules/PublicSale/BuyForm/index.tsx index f76487d04..81ef64661 100644 --- a/src/modules/PublicSale/BuyForm/index.tsx +++ b/src/modules/PublicSale/BuyForm/index.tsx @@ -321,9 +321,9 @@ const PrivateSaleForm = ({ vcInfo }: { vcInfo?: VCInfo }) => { lineHeight={1} fontWeight={400} color={'#000'} - _hover={{ - color: '#FA4E0E', - }} + // _hover={{ + // color: '#FA4E0E', + // }} > div { + color: #FA4E0E; + text-decoration: underline; + } + } + } } :global { From b5bc3bb20ad3b17d8ed2ab1f6f7a49f81c476524 Mon Sep 17 00:00:00 2001 From: 0xmegalodon Date: Wed, 31 Jan 2024 11:13:51 +0700 Subject: [PATCH 24/50] add tooltip & login --- src/modules/PublicSale/depositModal/login.tooltip.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/PublicSale/depositModal/login.tooltip.tsx b/src/modules/PublicSale/depositModal/login.tooltip.tsx index bac552b4d..eaf54d1b2 100644 --- a/src/modules/PublicSale/depositModal/login.tooltip.tsx +++ b/src/modules/PublicSale/depositModal/login.tooltip.tsx @@ -130,7 +130,7 @@ const LoginTooltip = ({ onClose }: { onClose: any }) => { color={'#000000'} gap={1} > - Sign in to X and claim your boost! + Sign in to X and claim your boost! {showManualCheck && ( Date: Wed, 31 Jan 2024 11:23:59 +0700 Subject: [PATCH 25/50] chore: update ui --- .../activities/components/NakaCountDown.tsx | 7 +++++- src/modules/PublicSale/activities/index.tsx | 24 ++++++++++++++++--- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/modules/PublicSale/activities/components/NakaCountDown.tsx b/src/modules/PublicSale/activities/components/NakaCountDown.tsx index 0d0df62cd..53725461f 100644 --- a/src/modules/PublicSale/activities/components/NakaCountDown.tsx +++ b/src/modules/PublicSale/activities/components/NakaCountDown.tsx @@ -7,9 +7,14 @@ import Countdown from '@/modules/Whitelist/stepAirdrop/Countdown'; import SvgInset from '@/components/SvgInset'; import { CDN_URL_ICONS } from '@/config'; import { formatCurrency, formatString } from '@/utils/format'; +import BigNumber from 'bignumber.js'; +import { useAppSelector } from '@/stores/hooks'; +import { coinPricesSelector } from '@/stores/states/common/selector'; +import { Coin } from '@/stores/states/common/types'; const NakaCountDown = React.memo(() => { const { bestPNL } = useTradeNakaData(); + const btcPrice = useAppSelector(coinPricesSelector)?.[Coin.BTC]; if (!bestPNL || !bestPNL.to_time || !bestPNL.from_time) return <>; return ( @@ -34,7 +39,7 @@ const NakaCountDown = React.memo(() => { if (!bestPNL?.winner?.twitter_username) return; window.open(`https://twitter.com/${bestPNL?.winner?.twitter_username}`, '_blank'); }}> - {formatString(bestPNL?.winner?.twitter_name || bestPNL?.winner?.address , 6)} +{formatCurrency(bestPNL?.winner?.realized_pnl || '0', 0, 5)} BTC + {formatString(bestPNL?.winner?.twitter_name || bestPNL?.winner?.address , 6)} +${formatCurrency(new BigNumber(bestPNL?.winner?.realized_pnl || '0').times(btcPrice).toNumber(), 0, 4)}
) : ( diff --git a/src/modules/PublicSale/activities/index.tsx b/src/modules/PublicSale/activities/index.tsx index bdb20e56c..db82933f2 100644 --- a/src/modules/PublicSale/activities/index.tsx +++ b/src/modules/PublicSale/activities/index.tsx @@ -25,6 +25,16 @@ interface ICTA { link?: string; } +enum ActivityType { + Day1, + Day2, + Day3, + Day4, + Day5, + Day6, + Day7 +} + export interface GameItemProps { key: number; tag: string; @@ -32,6 +42,7 @@ export interface GameItemProps { desc: string | any; src: string; ctas?: ICTA[]; + type: ActivityType } const Activities = React.memo(() => { @@ -49,6 +60,7 @@ const Activities = React.memo(() => { title: 'Fully on-chain gaming on Bitcoin', src: 'public-sale/playGame.png', ctas: [], + type: ActivityType.Day1, desc: ` Bitcoin Arcade is a Bitcoin L2 designed for gaming (aka. the Immutable of Bitcoin). It’s powered by BVM with these modules: Bitcoin for security, EigenDA for data availability, and Optimism for execution.

On the first day of BVM’s launch, you’ll play incredibly fun games. These are the first fully on-chain on Bitcoin. Both the game logic and game states are stored on-chain.

@@ -62,6 +74,7 @@ Good luck and have fun! tag: 'Day 2', title: 'BRC-20 Perpetual Futures on Bitcoin', src: 'public-sale/playGame.png', + type: ActivityType.Day2, ctas: [ { title: 'Trade on Naka', @@ -85,6 +98,7 @@ Good luck and have fun! tag: 'Day 3', title: 'Modular on Bitcoin', src: 'public-sale/playGame.png', + type: ActivityType.Day3, ctas: [ { title: 'Play with modular blocks', @@ -99,6 +113,7 @@ Good luck and have fun! tag: 'Day 4', title: 'Fully on-chain poker on Bitcoin', src: 'public-sale/playGame.png', + type: ActivityType.Day4, ctas: [ { title: 'Play games on Arcade', @@ -111,6 +126,7 @@ Good luck and have fun! { key: 4, tag: 'Day 5', + type: ActivityType.Day5, title: 'Running Bitcoin', src: 'public-sale/playGame.png', ctas: [ @@ -125,6 +141,7 @@ Good luck and have fun! { key: 5, tag: 'Day 6', + type: ActivityType.Day6, title: 'Running Bitcoin', src: 'public-sale/playGame.png', ctas: [ @@ -139,6 +156,7 @@ Good luck and have fun! { key: 6, tag: 'Day 7', + type: ActivityType.Day7, title: 'AI x Bitcoin', src: 'public-sale/playGame.png', desc: 'Details of Day 7 will be provided as soon as Day 6 is completed.', @@ -218,8 +236,8 @@ Good luck and have fun! } }; - const renderItem = (item: GameItemProps, index: number) => { - const isDisable = index > currentDay.diffDay; + const renderItem = (item: GameItemProps) => { + const isDisable = item.key > currentDay.diffDay; const title = isDisable ? item.title : item.title; return ( @@ -263,7 +281,7 @@ Good luck and have fun! className={styles.itemWrapper_desc} dangerouslySetInnerHTML={{ __html: item.desc }} /> - {currentDay.diffDay === expandIndex && expandIndex === index && index === 1 && ( + {currentDay.diffDay === expandIndex && expandIndex === item.key && item.key === 1 && ( )} From e15bb416d50dbd7731ab6f59074a636f923c9259 Mon Sep 17 00:00:00 2001 From: 0xmegalodon Date: Wed, 31 Jan 2024 11:24:40 +0700 Subject: [PATCH 26/50] add tooltip & login --- src/modules/PublicSale/activities/index.tsx | 1 + src/modules/PublicSale/activities/styles.module.scss | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/modules/PublicSale/activities/index.tsx b/src/modules/PublicSale/activities/index.tsx index c0b052b00..34950f376 100644 --- a/src/modules/PublicSale/activities/index.tsx +++ b/src/modules/PublicSale/activities/index.tsx @@ -228,6 +228,7 @@ Good luck and have fun! justifyContent={'space-between'} className={cs(styles.itemWrapper_header, { [styles.itemWrapper_header__active]: isExpanded, + [styles.itemWrapper_header__disable]: isDisable, })} > Date: Wed, 31 Jan 2024 11:28:14 +0700 Subject: [PATCH 27/50] uopdate --- src/modules/PublicSale/raffleButton/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/PublicSale/raffleButton/index.tsx b/src/modules/PublicSale/raffleButton/index.tsx index ebd28b289..0a1fdcf24 100644 --- a/src/modules/PublicSale/raffleButton/index.tsx +++ b/src/modules/PublicSale/raffleButton/index.tsx @@ -43,7 +43,7 @@ const RaffleButton = ({ className }: any) => { AuthenStorage.getAuthenKey() || AuthenStorage.getGuestAuthenKey(); const handleShareTw = () => { - const url = `https://twitter.com/BVMnetwork/status/1752174033100226567`; + const url = `https://twitter.com/BVMnetwork/status/1752546771560239400`; window.open(url, '_blank'); joinRafflePrograme(programeInfo?.id as number); @@ -256,7 +256,7 @@ const RaffleButton = ({ className }: any) => { From eabe3b6887dc3c2829e0a7bf1be557a7ff691fe9 Mon Sep 17 00:00:00 2001 From: camewell <130561684+camewell071@users.noreply.github.com> Date: Wed, 31 Jan 2024 11:43:22 +0700 Subject: [PATCH 28/50] chore: update copy --- src/modules/PublicSale/activities/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/PublicSale/activities/index.tsx b/src/modules/PublicSale/activities/index.tsx index 18d0f9634..be87a1b1e 100644 --- a/src/modules/PublicSale/activities/index.tsx +++ b/src/modules/PublicSale/activities/index.tsx @@ -90,7 +90,7 @@ Good luck and have fun! }, ], desc: 'NakaChain is a low-cost and lightning-fast Bitcoin Layer 2 blockchain designed for DeFi apps, enabling the payment of gas fees in Bitcoin. It’s powered by BVM with these modules: Bitcoin for security, Polygon for data availability, and Optimism for execution.' + - '

On the second day of awesomeness, challenge yourself to dominate the market by trading futures on BRC-20 tokens\' prices. The top gainer will be rewarded every 2 hours.' + + '

On the second day of awesomeness, challenge yourself to dominate the market by trading futures on BRC-20 tokens\' prices. Every two hours, the top gainer will earn $250 in Bitcoin.\n' + '

Total rewards: $3,000', }, { From 29487c77e47bb53c1522839db4eb5122b3af496e Mon Sep 17 00:00:00 2001 From: camewell <130561684+camewell071@users.noreply.github.com> Date: Wed, 31 Jan 2024 11:52:12 +0700 Subject: [PATCH 29/50] chore: update code --- src/modules/PublicSale/activities/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/PublicSale/activities/index.tsx b/src/modules/PublicSale/activities/index.tsx index be87a1b1e..66f19c732 100644 --- a/src/modules/PublicSale/activities/index.tsx +++ b/src/modules/PublicSale/activities/index.tsx @@ -172,7 +172,7 @@ Good luck and have fun! .toNumber(); // Case naka start at 4h UTC - if (diffDay === 1 && dayjs.utc().hour() < 4) { + if (diffDay === ActivityType.Day2 && dayjs.utc().hour() < 4) { diffDay = 0; } From d7ab63b8bab64e4703e4f01a09f84676dda3637f Mon Sep 17 00:00:00 2001 From: camewell <130561684+camewell071@users.noreply.github.com> Date: Wed, 31 Jan 2024 11:52:31 +0700 Subject: [PATCH 30/50] chore: update text --- src/modules/Whitelist/leaderBoard/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/modules/Whitelist/leaderBoard/index.tsx b/src/modules/Whitelist/leaderBoard/index.tsx index 622f24545..bbc1e6842 100644 --- a/src/modules/Whitelist/leaderBoard/index.tsx +++ b/src/modules/Whitelist/leaderBoard/index.tsx @@ -930,7 +930,6 @@ const LeaderBoard = (props: IProps) => { {/* {*/} - {/* console.log('SANG TEST: ');*/} {/* refParams.current = {*/} {/* ...refParams.current,*/} {/* page: refParams.current.page + 1,*/} From edd0e72837048ff578179aeb41e8d86fe72210e1 Mon Sep 17 00:00:00 2001 From: 0xmegalodon Date: Wed, 31 Jan 2024 12:03:48 +0700 Subject: [PATCH 31/50] add tooltip & login --- .../PublicSale/leaderBoardVisual/index.tsx | 2 +- src/modules/PublicSale/raffleButton/index.tsx | 29 ++++++++++++------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/modules/PublicSale/leaderBoardVisual/index.tsx b/src/modules/PublicSale/leaderBoardVisual/index.tsx index 50ba1d250..f39f7c836 100644 --- a/src/modules/PublicSale/leaderBoardVisual/index.tsx +++ b/src/modules/PublicSale/leaderBoardVisual/index.tsx @@ -198,7 +198,7 @@ const LeaderBoardVisual = (props: IProps) => { listRender.map((item, index) => { return <> + isYou={user?.twitter_id === item?.twitter_id} key={item?.twitter_id || item?.twitter_username}/> { item?.lastRender && diff --git a/src/modules/PublicSale/raffleButton/index.tsx b/src/modules/PublicSale/raffleButton/index.tsx index 597830b47..b8d65b2ba 100644 --- a/src/modules/PublicSale/raffleButton/index.tsx +++ b/src/modules/PublicSale/raffleButton/index.tsx @@ -1,6 +1,4 @@ import { - Box, - Button, Center, Flex, Popover, @@ -19,7 +17,6 @@ import React, { useEffect, useState } from 'react'; import cx from 'clsx'; import { useAppSelector } from '@/stores/hooks'; import { userSelector } from '@/stores/states/user/selector'; -import { getLink } from '@/utils/helpers'; import { getPublicSaleProgram, getPublicSaleSummary, @@ -28,9 +25,9 @@ import { joinRafflePrograme, } from '@/services/public-sale'; import AuthenStorage from '@/utils/storage/authen.storage'; -import DepositClaimItHere from '@/modules/PublicSale/depositModal/deposit.claim.it.here'; import { formatCurrency } from '@/utils/format'; -import { isMobile } from 'react-device-detect'; +import BigNumber from 'bignumber.js'; +import { PUBLIC_SALE_START } from '@/modules/Whitelist'; const RaffleButton = ({ className }: any) => { const { isOpen, onOpen, onClose } = useDisclosure(); @@ -102,6 +99,18 @@ const RaffleButton = ({ className }: any) => { ); }; + const currentDay = React.useMemo(() => { + const diffDay = new BigNumber( + dayjs.utc(PUBLIC_SALE_START).diff(dayjs.utc(), 'days'), + ) + .absoluteValue() + .toNumber(); + return { + // step: DAYS.length > diffDay ? DAYS[diffDay] : DAYS[DAYS.length - 1], + diffDay, + }; + }, []); + return ( !isLoading && ( @@ -116,7 +125,7 @@ const RaffleButton = ({ className }: any) => { lineHeight={'12px'} fontWeight={400} > - Daily Raffle + Day {currentDay?.diffDay + 1} Raffle { onClick={handleShareTw} cursor="pointer" > - - Like and repost to join + + Enter the raffle { cursor="pointer" mt={'20px'} > - Like and repost to join + Enter the raffle { cursor="pointer" mt={'20px'} > - Like and repost to join + Enter the raffle Date: Wed, 31 Jan 2024 13:57:19 +0700 Subject: [PATCH 32/50] add tooltip & login --- src/modules/PublicSale/raffleButton/index.tsx | 35 ++++++------------- .../raffleButton/styles.module.scss | 5 ++- 2 files changed, 13 insertions(+), 27 deletions(-) diff --git a/src/modules/PublicSale/raffleButton/index.tsx b/src/modules/PublicSale/raffleButton/index.tsx index b8d65b2ba..adbe53e44 100644 --- a/src/modules/PublicSale/raffleButton/index.tsx +++ b/src/modules/PublicSale/raffleButton/index.tsx @@ -188,38 +188,25 @@ const RaffleButton = ({ className }: any) => { <> - - Enter the raffle - - - - - + + + + - - + + + + + Enter the raffle + )} diff --git a/src/modules/PublicSale/raffleButton/styles.module.scss b/src/modules/PublicSale/raffleButton/styles.module.scss index 338f300e7..732065874 100644 --- a/src/modules/PublicSale/raffleButton/styles.module.scss +++ b/src/modules/PublicSale/raffleButton/styles.module.scss @@ -148,12 +148,11 @@ .learnMoreWrapper { background: #ffffff; - padding: 4px 6px 4px 16px; - width: fit-content; + padding: 4px; color: #000000; font-size: 14px; align-items: center; - justify-content: center; + //justify-content: center; height: 32px; gap: 8px; width: 100%; From 0a7044be787e627688f21b4d58f4d74fde7e2fc4 Mon Sep 17 00:00:00 2001 From: wilfred Date: Wed, 31 Jan 2024 14:14:51 +0700 Subject: [PATCH 33/50] update link --- src/modules/PublicSale/raffleButton/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/PublicSale/raffleButton/index.tsx b/src/modules/PublicSale/raffleButton/index.tsx index 0a1fdcf24..4d5169da0 100644 --- a/src/modules/PublicSale/raffleButton/index.tsx +++ b/src/modules/PublicSale/raffleButton/index.tsx @@ -43,7 +43,7 @@ const RaffleButton = ({ className }: any) => { AuthenStorage.getAuthenKey() || AuthenStorage.getGuestAuthenKey(); const handleShareTw = () => { - const url = `https://twitter.com/BVMnetwork/status/1752546771560239400`; + const url = `https://twitter.com/BVMnetwork/status/1752550686095798386`; window.open(url, '_blank'); joinRafflePrograme(programeInfo?.id as number); From 3119e8aca66295df5301777dea6c04c71d9355cb Mon Sep 17 00:00:00 2001 From: 0xmegalodon Date: Wed, 31 Jan 2024 14:42:33 +0700 Subject: [PATCH 34/50] add tooltip & login --- src/modules/PublicSale/raffleButton/index.tsx | 91 +++++-------------- .../raffleButton/styles.module.scss | 2 +- 2 files changed, 26 insertions(+), 67 deletions(-) diff --git a/src/modules/PublicSale/raffleButton/index.tsx b/src/modules/PublicSale/raffleButton/index.tsx index 726987a7c..fe1fc75c3 100644 --- a/src/modules/PublicSale/raffleButton/index.tsx +++ b/src/modules/PublicSale/raffleButton/index.tsx @@ -164,32 +164,18 @@ const RaffleButton = ({ className }: any) => { justifyContent: 'flex-start', }} > - - - - + + + + - - + + - + Share now @@ -213,7 +199,6 @@ const RaffleButton = ({ className }: any) => { - Enter the raffle @@ -251,37 +236,24 @@ const RaffleButton = ({ className }: any) => { - Enter the raffle - - - - + + + + - - + + + Enter the raffle
@@ -289,37 +261,24 @@ const RaffleButton = ({ className }: any) => { <> - Enter the raffle - - - - + + + + - - + + + Enter the raffle )} diff --git a/src/modules/PublicSale/raffleButton/styles.module.scss b/src/modules/PublicSale/raffleButton/styles.module.scss index 732065874..84dd0f8af 100644 --- a/src/modules/PublicSale/raffleButton/styles.module.scss +++ b/src/modules/PublicSale/raffleButton/styles.module.scss @@ -148,7 +148,7 @@ .learnMoreWrapper { background: #ffffff; - padding: 4px; + padding: 4px 12px 4px 4px; color: #000000; font-size: 14px; align-items: center; From 4e24a8e1288c180d2888981ce911a4d5f3ab0102 Mon Sep 17 00:00:00 2001 From: camewell <130561684+camewell071@users.noreply.github.com> Date: Wed, 31 Jan 2024 15:02:06 +0700 Subject: [PATCH 35/50] chore: update ui --- src/modules/PublicSale/activities/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/PublicSale/activities/index.tsx b/src/modules/PublicSale/activities/index.tsx index 66f19c732..c494e6c4f 100644 --- a/src/modules/PublicSale/activities/index.tsx +++ b/src/modules/PublicSale/activities/index.tsx @@ -90,8 +90,8 @@ Good luck and have fun! }, ], desc: 'NakaChain is a low-cost and lightning-fast Bitcoin Layer 2 blockchain designed for DeFi apps, enabling the payment of gas fees in Bitcoin. It’s powered by BVM with these modules: Bitcoin for security, Polygon for data availability, and Optimism for execution.' + - '

On the second day of awesomeness, challenge yourself to dominate the market by trading futures on BRC-20 tokens\' prices. Every two hours, the top gainer will earn $250 in Bitcoin.\n' + - '

Total rewards: $3,000', + '

On the second day of awesomeness, challenge yourself to dominate the market by trading futures on BRC-20 tokens\' prices. Every two hours, the top gainer will earn $50 in Bitcoin.\n' + + '

Total rewards: $1,100', }, { key: 2, From e10e4fe3cd4e2dee8c05fa7263f7df63f3ff3e6d Mon Sep 17 00:00:00 2001 From: camewell <130561684+camewell071@users.noreply.github.com> Date: Wed, 31 Jan 2024 15:22:56 +0700 Subject: [PATCH 36/50] chore: update ui --- src/modules/PublicSale/activities/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/PublicSale/activities/index.tsx b/src/modules/PublicSale/activities/index.tsx index c494e6c4f..e0bf3969b 100644 --- a/src/modules/PublicSale/activities/index.tsx +++ b/src/modules/PublicSale/activities/index.tsx @@ -91,7 +91,7 @@ Good luck and have fun! ], desc: 'NakaChain is a low-cost and lightning-fast Bitcoin Layer 2 blockchain designed for DeFi apps, enabling the payment of gas fees in Bitcoin. It’s powered by BVM with these modules: Bitcoin for security, Polygon for data availability, and Optimism for execution.' + '

On the second day of awesomeness, challenge yourself to dominate the market by trading futures on BRC-20 tokens\' prices. Every two hours, the top gainer will earn $50 in Bitcoin.\n' + - '

Total rewards: $1,100', + '

Total rewards: $1,000', }, { key: 2, From 6b3d66fde6f824fd55553ea384a6172c64d54d6e Mon Sep 17 00:00:00 2001 From: 0xmegalodon Date: Wed, 31 Jan 2024 15:50:41 +0700 Subject: [PATCH 37/50] add tooltip & login --- src/modules/PublicSale/aboveTheFold/index.tsx | 4 +--- src/modules/PublicSale/leaderBoardVisual/index.tsx | 2 +- src/modules/PublicSale/topHeader/index.tsx | 7 ++----- src/stores/states/common/reducer.ts | 2 +- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/modules/PublicSale/aboveTheFold/index.tsx b/src/modules/PublicSale/aboveTheFold/index.tsx index 8f3f6f21f..bf6644a58 100644 --- a/src/modules/PublicSale/aboveTheFold/index.tsx +++ b/src/modules/PublicSale/aboveTheFold/index.tsx @@ -10,9 +10,7 @@ import { VCInfo } from '@/interfaces/vc'; import LeaderBoardVisual from '@/modules/PublicSale/leaderBoardVisual'; import RaffleButton from '@/modules/PublicSale/raffleButton'; import Activities from '@/modules/PublicSale/activities'; -import LeaderBoardSwitch from '@/modules/PublicSale/leaderBoardSwitch'; import RewardButton from '../rewardButton'; -import cs from 'classnames'; import useWindowSize from '@/hooks/useWindowSize'; const AboveTheFold = () => { @@ -58,7 +56,7 @@ const AboveTheFold = () => {
- + {/**/} {mobileScreen && }
diff --git a/src/modules/PublicSale/leaderBoardVisual/index.tsx b/src/modules/PublicSale/leaderBoardVisual/index.tsx index f39f7c836..b7eaf5fdf 100644 --- a/src/modules/PublicSale/leaderBoardVisual/index.tsx +++ b/src/modules/PublicSale/leaderBoardVisual/index.tsx @@ -28,7 +28,7 @@ const LeaderBoardVisual = (props: IProps) => { const [listMissingRender, setListMissingRender] = useState([]); const needReload = useAppSelector(commonSelector).needReload; const dispatch = useAppDispatch(); - const leaderBoardMode = useSelector(commonSelector).leaderBoardMode; + const leaderBoardMode = LEADER_BOARD_MODE.ALL; const latestContributors = useRef([]); const animatedLatestContributors = useRef([]); const user = useAppSelector(userSelector); diff --git a/src/modules/PublicSale/topHeader/index.tsx b/src/modules/PublicSale/topHeader/index.tsx index 1bc3b75aa..364166640 100644 --- a/src/modules/PublicSale/topHeader/index.tsx +++ b/src/modules/PublicSale/topHeader/index.tsx @@ -1,9 +1,6 @@ import { Flex, Text } from '@chakra-ui/react'; import { useRouter } from 'next/navigation'; -import { ALLOW_LIST_URL, HOME_URL } from '@/constants/route-path'; import s from './styles.module.scss'; -import LeaderBoardSwitch from '@/modules/PublicSale/leaderBoardSwitch'; -import SvgInset from '@/components/SvgInset'; import React from 'react'; const TopHeader = () => { @@ -18,9 +15,9 @@ const TopHeader = () => { The first modular blockchain metaprotocol that lets
- + {/* - + */} ) diff --git a/src/stores/states/common/reducer.ts b/src/stores/states/common/reducer.ts index 50aa2328a..5aa5f2a9a 100644 --- a/src/stores/states/common/reducer.ts +++ b/src/stores/states/common/reducer.ts @@ -8,7 +8,7 @@ const initialState: CommonState = { [Coin.ETH]: '0', [Coin.TIA]: '0', } as any, - leaderBoardMode: 0, + leaderBoardMode: 1, needCheckDeposit: false, animatedLatestContributors: [], }; From 18ff538cb30428ce54e9d4a240c4d44f347dc325 Mon Sep 17 00:00:00 2001 From: wilfred Date: Wed, 31 Jan 2024 15:52:33 +0700 Subject: [PATCH 38/50] WIP --- src/modules/PublicSale/AuthForBuyV2/index.tsx | 60 ++++++++++++++ .../AuthForBuyV2/styles.module.scss | 27 ++++++ src/modules/PublicSale/BuyForm/index.tsx | 83 +++++++++++-------- src/stores/index.ts | 2 +- src/stores/states/user/reducer.ts | 5 ++ src/stores/states/user/selector.ts | 28 ++++--- src/stores/states/user/types.ts | 11 +-- 7 files changed, 164 insertions(+), 52 deletions(-) create mode 100644 src/modules/PublicSale/AuthForBuyV2/index.tsx create mode 100644 src/modules/PublicSale/AuthForBuyV2/styles.module.scss diff --git a/src/modules/PublicSale/AuthForBuyV2/index.tsx b/src/modules/PublicSale/AuthForBuyV2/index.tsx new file mode 100644 index 000000000..98793c7cc --- /dev/null +++ b/src/modules/PublicSale/AuthForBuyV2/index.tsx @@ -0,0 +1,60 @@ +import { userTokenSelector } from '@/stores/states/user/selector'; +import { Button, Flex, Tooltip, useDisclosure } from '@chakra-ui/react'; +import cx from 'classnames'; +import React, { PropsWithChildren, useMemo } from 'react'; +import { useSelector } from 'react-redux'; +import s from './styles.module.scss'; + +interface IAuthForBuyV2 extends PropsWithChildren {} + +const AuthForBuyV2: React.FC = ({ children }) => { + const userToken = useSelector(userTokenSelector); + + const isLogged = useMemo(() => Boolean(userToken), [userToken]); + + const { isOpen, onOpen, onClose } = useDisclosure(); + + if (isLogged) { + return children; + } + + return ( + <> + + + + + + + + ); +}; + +export default AuthForBuyV2; diff --git a/src/modules/PublicSale/AuthForBuyV2/styles.module.scss b/src/modules/PublicSale/AuthForBuyV2/styles.module.scss new file mode 100644 index 000000000..4770f41ad --- /dev/null +++ b/src/modules/PublicSale/AuthForBuyV2/styles.module.scss @@ -0,0 +1,27 @@ +.btnWrapper { + grid-gap: 16px; + grid-template-columns: 2fr 1fr; + + @include is-mobile { + grid-template-columns: 1fr; + } +} + +.btnContainer { + height: 48px !important; + padding: 8px 60px !important; + border-radius: 0px !important; + background: #fa4e0e !important; + color: #fff !important; + width: 100%; + font-weight: normal !important; + gap: 8px; + &.btnBuyAsGuest { + background: #ffffff !important; + color: #000000 !important; + } + &.btnBuyAndStake { + background: #000000 !important; + color: #ffffff !important; + } +} diff --git a/src/modules/PublicSale/BuyForm/index.tsx b/src/modules/PublicSale/BuyForm/index.tsx index 81ef64661..56958dae5 100644 --- a/src/modules/PublicSale/BuyForm/index.tsx +++ b/src/modules/PublicSale/BuyForm/index.tsx @@ -1,13 +1,24 @@ import { Box, Button, Flex, Text, Tooltip } from '@chakra-ui/react'; import { FormikProps, useFormik } from 'formik'; -import React, { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import React, { + forwardRef, + useCallback, + useEffect, + useMemo, + useRef, + useState, +} from 'react'; import s from './styles.module.scss'; import { getPublicSaleLeaderBoards, getPublicSaleSummary, postPublicsaleWalletInfoManualCheck, } from '@/services/public-sale'; -import { defaultSummary, IPublicSaleDepositInfo, VCInfo } from '@/interfaces/vc'; +import { + defaultSummary, + IPublicSaleDepositInfo, + VCInfo, +} from '@/interfaces/vc'; import { formatCurrency } from '@/utils/format'; import { toast } from 'react-hot-toast'; import dayjs from 'dayjs'; @@ -26,6 +37,7 @@ import { GuestCodeHere } from '../depositModal/deposit.guest.code'; import LoginTooltip from '@/modules/PublicSale/depositModal/login.tooltip'; import { useAppSelector } from '@/stores/hooks'; import { commonSelector } from '@/stores/states/common/selector'; +import AuthForBuyV2 from '../AuthForBuyV2'; interface FormValues { tokenAmount: string; @@ -175,14 +187,13 @@ const PrivateSaleForm = ({ vcInfo }: { vcInfo?: VCInfo }) => { lineHeight={1} fontWeight={400} color={'rgba(0,0,0,0.7)'} - gap={1} alignItems={"center"} + gap={1} + alignItems={'center'} > Your contribution - { - - }}/> + {}} /> - + {token ? `$${formatCurrency( @@ -247,8 +258,7 @@ const PrivateSaleForm = ({ vcInfo }: { vcInfo?: VCInfo }) => { : '-'} - ) - } + )}
@@ -256,25 +266,21 @@ const PrivateSaleForm = ({ vcInfo }: { vcInfo?: VCInfo }) => { }); const renderLoginTooltip = useCallback(() => { - return ( - token ? ( - } - > - - - ) : ( - - ) - ) + return token ? ( + } + > + + + ) : ( + + ); }, [token, userContributeInfo]); return ( @@ -381,16 +387,23 @@ const PrivateSaleForm = ({ vcInfo }: { vcInfo?: VCInfo }) => { {/* */} {/*)}*/} -
- { - renderLoginTooltip() - } -
+
{renderLoginTooltip()}
- + + + + {/* - + */} {parseFloat(userContributeInfo?.usdt_value || '0') > 0 && ( diff --git a/src/stores/index.ts b/src/stores/index.ts index afee6af6e..53da83220 100644 --- a/src/stores/index.ts +++ b/src/stores/index.ts @@ -10,7 +10,7 @@ const reducers = combineReducers(reducer); const persistConfig = getPersistConfig({ key: 'root', storage: persistLocalStorage, - whitelist: ['common.poolTabIndex', 'common.coinPrices', 'airdrop'], + whitelist: ['common.poolTabIndex', 'common.coinPrices', 'airdrop', 'user'], rootReducer: reducers, }); diff --git a/src/stores/states/user/reducer.ts b/src/stores/states/user/reducer.ts index 797534210..31905545a 100644 --- a/src/stores/states/user/reducer.ts +++ b/src/stores/states/user/reducer.ts @@ -20,6 +20,7 @@ const initialState: UserState = { airdropGMHolders: null, airdropGenerativeUsers: null, airdropPerceptronsHolders: null, + userToken: null, } as any; const slice = createSlice({ @@ -93,6 +94,9 @@ const slice = createSlice({ guest_code: action.payload, } as any; }, + setUserToken: (state, action) => { + state.userToken = action.payload; + }, }, }); @@ -110,6 +114,7 @@ export const { clearPublicSaleLeaderBoard, setPublicSaleLeaderBoardVisual, setGuestSecretCode, + setUserToken } = slice.actions; export default slice.reducer; diff --git a/src/stores/states/user/selector.ts b/src/stores/states/user/selector.ts index ba1141b1a..13df04199 100644 --- a/src/stores/states/user/selector.ts +++ b/src/stores/states/user/selector.ts @@ -3,34 +3,40 @@ import { EVMFieldType, User } from '@/stores/states/user/types'; import { ILeaderBoardPoint } from '@/interfaces/leader-board-point'; import { SignatureStatus } from '@/interfaces/whitelist'; -export const userSelector = (state: RootState) => state.user?.user as User | undefined; +export const userSelector = (state: RootState) => + state.user?.user as User | undefined; +export const userTokenSelector = (state: RootState) => state.user?.userToken; export const leaderBoardSelector = (state: RootState) => ({ list: (state.user?.leaderBoard || []) as ILeaderBoardPoint[], - count: (state.user?.leaderBoardCount || '') as string + count: (state.user?.leaderBoardCount || '') as string, }); export const allowBTCSelector = (state: RootState) => ({ status: (state.user?.allowBTC?.status || []) as SignatureStatus[], - loaded: (state.user?.allowBTC?.loaded || false) as boolean + loaded: (state.user?.allowBTC?.loaded || false) as boolean, }); export const allowCelestiaSelector = (state: RootState) => ({ status: (state.user?.allowCelestia?.status || []) as SignatureStatus[], - loaded: (state.user?.allowCelestia?.loaded || false) as boolean + loaded: (state.user?.allowCelestia?.loaded || false) as boolean, }); export const allowEVMSelector = (state: RootState) => (type: EVMFieldType) => { const data = (state.user as any)?.[type]; - return ({ + return { status: (data?.status || []) as SignatureStatus[], - loaded: (data?.allowCelestia?.loaded || false) as boolean - }) + loaded: (data?.allowCelestia?.loaded || false) as boolean, + }; }; -export const airdropAlphaUsersSelector = (state: RootState) => state.user.airdropAlphaUsers; -export const airdropGMHoldersSelector = (state: RootState) => state.user.airdropGMHolders; -export const airdropGenerativeUsersSelector = (state: RootState) => state.user.airdropGenerativeUsers; -export const airdropPerceptronsHoldersSelector = (state: RootState) => state.user.airdropPerceptronsHolders; +export const airdropAlphaUsersSelector = (state: RootState) => + state.user.airdropAlphaUsers; +export const airdropGMHoldersSelector = (state: RootState) => + state.user.airdropGMHolders; +export const airdropGenerativeUsersSelector = (state: RootState) => + state.user.airdropGenerativeUsers; +export const airdropPerceptronsHoldersSelector = (state: RootState) => + state.user.airdropPerceptronsHolders; export const publicSaleLeaderBoardSelector = (state: RootState) => ({ list: (state.user?.publicSaleLeaderBoard || []) as ILeaderBoardPoint[], diff --git a/src/stores/states/user/types.ts b/src/stores/states/user/types.ts index 501cac9b1..e50b8857d 100644 --- a/src/stores/states/user/types.ts +++ b/src/stores/states/user/types.ts @@ -23,27 +23,28 @@ export interface User { num_post: string; boost: string; guest_code: string; - view_boost: string + view_boost: string; } -export type EVMFieldType = "allowOptimism" +export type EVMFieldType = 'allowOptimism'; export interface UserState { - user?: User | undefined, + user?: User | undefined; leaderBoard: ILeaderBoardPoint[]; leaderBoardCount: string; allowBTC: { status: SignatureStatus[]; loaded: boolean; - }, + }; allowCelestia: { status: SignatureStatus[]; loaded: boolean; - }, + }; airdropAlphaUsers: any; airdropGMHolders: any; airdropGenerativeUsers: any; airdropPerceptronsHolders: any; publicSaleLeaderBoard: ILeaderBoardPoint[]; publicSaleLeaderBoardVisual: ILeaderBoardPoint[]; + userToken: string; } From 1cc147782b7098ce8ff3aae674b6fd24a22546c6 Mon Sep 17 00:00:00 2001 From: 0xmegalodon Date: Wed, 31 Jan 2024 15:52:56 +0700 Subject: [PATCH 39/50] add tooltip & login --- src/modules/PublicSale/aboveTheFold/styles.module.scss | 2 +- src/modules/PublicSale/leaderBoardVisual/styles.module.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/PublicSale/aboveTheFold/styles.module.scss b/src/modules/PublicSale/aboveTheFold/styles.module.scss index 8f0270490..bd94056cf 100644 --- a/src/modules/PublicSale/aboveTheFold/styles.module.scss +++ b/src/modules/PublicSale/aboveTheFold/styles.module.scss @@ -23,7 +23,7 @@ .leftSection { background: #1b1b1b; - padding-top: 80px; + padding-top: 40px; position: relative; @include is-mobile { padding-top: 130px; diff --git a/src/modules/PublicSale/leaderBoardVisual/styles.module.scss b/src/modules/PublicSale/leaderBoardVisual/styles.module.scss index 3738e0ecb..7c06b9775 100644 --- a/src/modules/PublicSale/leaderBoardVisual/styles.module.scss +++ b/src/modules/PublicSale/leaderBoardVisual/styles.module.scss @@ -50,7 +50,7 @@ align-content: flex-start; @include is-mobile{ - margin-top: 130px; + margin-top: 80px; } } From 58ca9d4423f448504bdb0c275b9af8209b71591e Mon Sep 17 00:00:00 2001 From: wilfred Date: Wed, 31 Jan 2024 16:01:31 +0700 Subject: [PATCH 40/50] hotfix remove recaptcha --- .../PublicSale/AuthForBuy/btnCreateGuest.tsx | 41 ++++++++++++------ .../PublicSale/AuthForBuy/importOrCreate.tsx | 43 +++++++++++++------ .../depositModal/deposit.content.tsx | 37 +++++++++------- src/services/public-sale.ts | 4 +- 4 files changed, 79 insertions(+), 46 deletions(-) diff --git a/src/modules/PublicSale/AuthForBuy/btnCreateGuest.tsx b/src/modules/PublicSale/AuthForBuy/btnCreateGuest.tsx index 720155ee6..a31cfd984 100644 --- a/src/modules/PublicSale/AuthForBuy/btnCreateGuest.tsx +++ b/src/modules/PublicSale/AuthForBuy/btnCreateGuest.tsx @@ -1,6 +1,6 @@ import SvgInset from '@/components/SvgInset'; import { Button, Center, Spinner, Text } from '@chakra-ui/react'; -import React, { useCallback, useState } from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; import s from './styles.module.scss'; import { useGoogleReCaptcha } from 'react-google-recaptcha-v3'; import { generateRandomString } from '@/utils/encryption'; @@ -9,28 +9,41 @@ import AuthenStorage from '@/utils/storage/authen.storage'; import { setGuestSecretCode } from '@/stores/states/user/reducer'; import { useDispatch } from 'react-redux'; import cs from 'classnames'; +import { userSelector } from '@/stores/states/user/selector'; +import { useAppSelector } from '@/stores/hooks'; const BtnCreateGuest = () => { const dispatch = useDispatch(); const { executeRecaptcha } = useGoogleReCaptcha(); const [loading, setLoading] = useState(false); - const createNewSecretCode = useCallback(() => { + const user = useAppSelector(userSelector); + const isAuth = useMemo(() => user?.guest_code || user?.twitter_id, [user]); + // const createNewSecretCode = useCallback(() => { + // try { + // if (!executeRecaptcha) { + // console.log('Execute recaptcha not yet available'); + // throw Error('Execute recaptcha not yet available'); + // } + // executeRecaptcha('enquiryFormSubmit').then((gReCaptchaToken) => { + // console.log(gReCaptchaToken, 'response Google reCaptcha server'); + // getToken(gReCaptchaToken); + // }); + // } catch (error) { + // // + // } + // }, [executeRecaptcha]); + + const createNewSecretCode = async () => { try { - if (!executeRecaptcha) { - console.log('Execute recaptcha not yet available'); - throw Error('Execute recaptcha not yet available'); - } - executeRecaptcha('enquiryFormSubmit').then((gReCaptchaToken) => { - console.log(gReCaptchaToken, 'response Google reCaptcha server'); - getToken(gReCaptchaToken); - }); - } catch (error) { - // - } - }, [executeRecaptcha]); + await getToken('gReCaptchaToken'); + } catch (error) {} + }; const getToken = async (captcha: string, code?: string) => { try { + if (isAuth) { + return; + } setLoading(true); const _secretCode = generateRandomString(10); diff --git a/src/modules/PublicSale/AuthForBuy/importOrCreate.tsx b/src/modules/PublicSale/AuthForBuy/importOrCreate.tsx index 449fe24d9..283f53f16 100644 --- a/src/modules/PublicSale/AuthForBuy/importOrCreate.tsx +++ b/src/modules/PublicSale/AuthForBuy/importOrCreate.tsx @@ -12,21 +12,27 @@ import { Text, Box, } from '@chakra-ui/react'; -import React, { useCallback, useState } from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; import { useGoogleReCaptcha } from 'react-google-recaptcha-v3'; import { useDispatch } from 'react-redux'; import s from './styles.module.scss'; +import { userSelector } from '@/stores/states/user/selector'; +import { useAppSelector } from '@/stores/hooks'; const ImportOrCreate = ({ onBack }: { onBack?: any }) => { const dispatch = useDispatch(); const getSecretCode = AuthenStorage.getGuestSecretKey(); + const user = useAppSelector(userSelector); + const [loading, setLoading] = useState(false); const [secretCode, setSecretCode] = useState(getSecretCode); const [isImport, setIsImport] = useState(false); const [importSecretKeyText, setImportSecretKeyText] = useState(''); const [secretKeyError, setSecretKeyError] = useState(''); + const isAuth = useMemo(() => user?.guest_code || user?.twitter_id, [user]); + const validatePassword = (password: string) => { // Regular expression to validate password const regex = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{10,}$/; @@ -37,6 +43,9 @@ const ImportOrCreate = ({ onBack }: { onBack?: any }) => { const getToken = async (captcha: string, code?: string) => { try { + if (isAuth) { + return; + } setLoading(true); const _secretCode = code || generateRandomString(10); @@ -51,20 +60,26 @@ const ImportOrCreate = ({ onBack }: { onBack?: any }) => { } }; - const createNewSecretCode = useCallback(() => { + // const createNewSecretCode = useCallback(() => { + // try { + // if (!executeRecaptcha) { + // console.log('Execute recaptcha not yet available'); + // throw Error('Execute recaptcha not yet available'); + // } + // executeRecaptcha('enquiryFormSubmit').then((gReCaptchaToken) => { + // console.log(gReCaptchaToken, 'response Google reCaptcha server'); + // getToken(gReCaptchaToken); + // }); + // } catch (error) { + // // + // } + // }, [executeRecaptcha]); + + const createNewSecretCode = async () => { try { - if (!executeRecaptcha) { - console.log('Execute recaptcha not yet available'); - throw Error('Execute recaptcha not yet available'); - } - executeRecaptcha('enquiryFormSubmit').then((gReCaptchaToken) => { - console.log(gReCaptchaToken, 'response Google reCaptcha server'); - getToken(gReCaptchaToken); - }); - } catch (error) { - // - } - }, [executeRecaptcha]); + await getToken('gReCaptchaToken'); + } catch (error) {} + }; const onImportSecretCode = useCallback( (code: string) => { diff --git a/src/modules/PublicSale/depositModal/deposit.content.tsx b/src/modules/PublicSale/depositModal/deposit.content.tsx index bf5919b6f..25cd389a7 100644 --- a/src/modules/PublicSale/depositModal/deposit.content.tsx +++ b/src/modules/PublicSale/depositModal/deposit.content.tsx @@ -72,21 +72,22 @@ const DepositContent: React.FC = ({ const isAuth = useMemo(() => user?.guest_code || user?.twitter_id, [user]); - const createNewSecretCode = () => { + const createNewSecretCode = async () => { try { - if (isAuth) { - setGenerating(false); - return; - } - if (!executeRecaptcha) { - console.log('Execute recaptcha not yet available'); - throw Error('Execute recaptcha not yet available'); - } - executeRecaptcha('enquiryFormSubmit').then((gReCaptchaToken) => { - console.log(gReCaptchaToken, 'response Google reCaptcha server'); + await getToken(''); + // if (isAuth) { + // setGenerating(false); + // return; + // } + // if (!executeRecaptcha) { + // console.log('Execute recaptcha not yet available'); + // throw Error('Execute recaptcha not yet available'); + // } + // executeRecaptcha('enquiryFormSubmit').then((gReCaptchaToken) => { + // console.log(gReCaptchaToken, 'response Google reCaptcha server'); - getToken(gReCaptchaToken); - }); + // getToken(gReCaptchaToken); + // }); } catch (error) { // } @@ -94,6 +95,9 @@ const DepositContent: React.FC = ({ const getToken = async (captcha: string, code?: string) => { try { + if (isAuth) { + return; + } const _secretCode = generateRandomString(10); const rs = await generateTOkenWithSecretCode(_secretCode, captcha); @@ -185,9 +189,10 @@ const DepositContent: React.FC = ({ return ( - Make a contribution using any of the currencies below.
After your - payment processes, you’ll get a confirmation code to claim your $BVM - allocation later. + Make a contribution using any of the currencies below. +
+ After your payment processes, you’ll get a confirmation code to claim + your $BVM allocation later.
{/* {secretCode && ( <> diff --git a/src/services/public-sale.ts b/src/services/public-sale.ts index 9ba0b93c5..c405b1193 100644 --- a/src/services/public-sale.ts +++ b/src/services/public-sale.ts @@ -40,14 +40,14 @@ export const postPublicsaleWalletInfoManualCheck = export const generateTOkenWithSecretCode = async ( secret_code: string, - recaptcha: string, + _recaptcha: string, ): Promise => { const res = (await apiClient.post( `/bvm/generate-token-with-secret-code`, { secret_code }, { headers: { - recaptcha, + // recaptcha, 'user-data': JSON.stringify({ screen: window?.location?.pathname, timezone: new Date().toString(), From 73d133611d9b014b5f38b63a07a6c688cabc309a Mon Sep 17 00:00:00 2001 From: camewell <130561684+camewell071@users.noreply.github.com> Date: Wed, 31 Jan 2024 16:05:14 +0700 Subject: [PATCH 41/50] chore: update ui --- src/modules/PublicSale/activities/index.tsx | 17 +++++++++-------- .../PublicSale/activities/styles.module.scss | 12 ++++++++---- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/modules/PublicSale/activities/index.tsx b/src/modules/PublicSale/activities/index.tsx index e0bf3969b..82ab4a782 100644 --- a/src/modules/PublicSale/activities/index.tsx +++ b/src/modules/PublicSale/activities/index.tsx @@ -12,7 +12,7 @@ import { Text, useDisclosure, } from '@chakra-ui/react'; import styles from './styles.module.scss'; -import { CDN_URL } from '@/config'; +import { CDN_URL, CDN_URL_ICONS } from '@/config'; import cs from 'classnames'; import SvgInset from '@/components/SvgInset'; import TradeNakaWinnersPopup from '@/modules/PublicSale/activities/components/TradeNakaWinnersPopup'; @@ -182,7 +182,7 @@ Good luck and have fun! }; }, []); - const [expandIndex, setExpandIndex] = React.useState(currentDay.diffDay) + const [expandIndex, setExpandIndex] = React.useState(undefined) const renderCta = (item: ICTA) => { switch (item.type) { @@ -261,16 +261,17 @@ Good luck and have fun! [styles.itemWrapper_title__active]: isExpanded, })} > - {item.tag}: {title} + {item.tag}: {title} {item.key === currentDay.diffDay && (Happening Now)}
@@ -306,7 +307,7 @@ Good luck and have fun!

7 days of awesomeness. Experience Bitcoin like never before.

- { + { setExpandIndex(expandedIndex as number) }}> {DAYS.map(renderItem)} diff --git a/src/modules/PublicSale/activities/styles.module.scss b/src/modules/PublicSale/activities/styles.module.scss index 4cf0d2a4d..8b1811fa1 100644 --- a/src/modules/PublicSale/activities/styles.module.scss +++ b/src/modules/PublicSale/activities/styles.module.scss @@ -59,6 +59,10 @@ max-width: 214px; } + span { + color: #FA4E0E; + } + @include is-mobile { font-size: 14px; } @@ -82,13 +86,13 @@ font-size: 14px; } - } &_header { padding: 10px 16px !important; background-color: rgba(black, .8); //border: 1px solid rgba(white, .10); cursor: default !important; + gap: 8px; button { padding: 0 !important; @@ -105,9 +109,9 @@ } &__disable { - button { - display: none !important; - } + //button { + // display: none !important; + //} } } From 9c9fbeb0641ac1feead0882b264308e22ba30ca3 Mon Sep 17 00:00:00 2001 From: wilfred Date: Wed, 31 Jan 2024 16:30:30 +0700 Subject: [PATCH 42/50] WIP --- src/modules/PublicSale/AuthForBuy/index.tsx | 61 +++-- src/modules/PublicSale/AuthForBuyV2/index.tsx | 215 ++++++++++++++---- .../AuthForBuyV2/styles.module.scss | 22 +- src/modules/PublicSale/BuyForm/index.tsx | 83 +++---- 4 files changed, 264 insertions(+), 117 deletions(-) diff --git a/src/modules/PublicSale/AuthForBuy/index.tsx b/src/modules/PublicSale/AuthForBuy/index.tsx index 3674e18c8..425c7dfa5 100644 --- a/src/modules/PublicSale/AuthForBuy/index.tsx +++ b/src/modules/PublicSale/AuthForBuy/index.tsx @@ -8,6 +8,7 @@ import { GoogleReCaptchaProvider } from 'react-google-recaptcha-v3'; import DepositContent from '../depositModal/deposit.content'; import s from './styles.module.scss'; import cx from 'clsx'; +import AuthForBuyV2 from '../AuthForBuyV2'; interface IAuthForBuy extends PropsWithChildren {} @@ -26,39 +27,49 @@ const AuthForBuy: React.FC = () => { return ( <> - - ( + + )} > - + + + + + + any; +} -const AuthForBuyV2: React.FC = ({ children }) => { +const AuthForBuyV2: React.FC = ({ + children, + renderWithoutLogin, +}) => { const userToken = useSelector(userTokenSelector); const isLogged = useMemo(() => Boolean(userToken), [userToken]); @@ -18,43 +24,176 @@ const AuthForBuyV2: React.FC = ({ children }) => { return children; } - return ( - <> - - - - + - - - - ); + + + + ); + } + + return <>; }; export default AuthForBuyV2; diff --git a/src/modules/PublicSale/AuthForBuyV2/styles.module.scss b/src/modules/PublicSale/AuthForBuyV2/styles.module.scss index 4770f41ad..90968d822 100644 --- a/src/modules/PublicSale/AuthForBuyV2/styles.module.scss +++ b/src/modules/PublicSale/AuthForBuyV2/styles.module.scss @@ -7,18 +7,28 @@ } } +.loginModal { + max-width: 400px !important; + header { + p { + color: white; + } + } +} + .btnContainer { height: 48px !important; - padding: 8px 60px !important; + padding: 6px !important; border-radius: 0px !important; - background: #fa4e0e !important; - color: #fff !important; + background: #ffffff !important; + color: #000000 !important; width: 100%; font-weight: normal !important; gap: 8px; - &.btnBuyAsGuest { - background: #ffffff !important; - color: #000000 !important; + justify-content: flex-start !important; + &.btnPrimary { + background: #fa4e0e !important; + color: #fff !important; } &.btnBuyAndStake { background: #000000 !important; diff --git a/src/modules/PublicSale/BuyForm/index.tsx b/src/modules/PublicSale/BuyForm/index.tsx index 56958dae5..81ef64661 100644 --- a/src/modules/PublicSale/BuyForm/index.tsx +++ b/src/modules/PublicSale/BuyForm/index.tsx @@ -1,24 +1,13 @@ import { Box, Button, Flex, Text, Tooltip } from '@chakra-ui/react'; import { FormikProps, useFormik } from 'formik'; -import React, { - forwardRef, - useCallback, - useEffect, - useMemo, - useRef, - useState, -} from 'react'; +import React, { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import s from './styles.module.scss'; import { getPublicSaleLeaderBoards, getPublicSaleSummary, postPublicsaleWalletInfoManualCheck, } from '@/services/public-sale'; -import { - defaultSummary, - IPublicSaleDepositInfo, - VCInfo, -} from '@/interfaces/vc'; +import { defaultSummary, IPublicSaleDepositInfo, VCInfo } from '@/interfaces/vc'; import { formatCurrency } from '@/utils/format'; import { toast } from 'react-hot-toast'; import dayjs from 'dayjs'; @@ -37,7 +26,6 @@ import { GuestCodeHere } from '../depositModal/deposit.guest.code'; import LoginTooltip from '@/modules/PublicSale/depositModal/login.tooltip'; import { useAppSelector } from '@/stores/hooks'; import { commonSelector } from '@/stores/states/common/selector'; -import AuthForBuyV2 from '../AuthForBuyV2'; interface FormValues { tokenAmount: string; @@ -187,13 +175,14 @@ const PrivateSaleForm = ({ vcInfo }: { vcInfo?: VCInfo }) => { lineHeight={1} fontWeight={400} color={'rgba(0,0,0,0.7)'} - gap={1} - alignItems={'center'} + gap={1} alignItems={"center"} > Your contribution - {}} /> + { + + }}/>
- + {token ? `$${formatCurrency( @@ -258,7 +247,8 @@ const PrivateSaleForm = ({ vcInfo }: { vcInfo?: VCInfo }) => { : '-'} - )} + ) + } @@ -266,21 +256,25 @@ const PrivateSaleForm = ({ vcInfo }: { vcInfo?: VCInfo }) => { }); const renderLoginTooltip = useCallback(() => { - return token ? ( - } - > - - - ) : ( - - ); + return ( + token ? ( + } + > + + + ) : ( + + ) + ) }, [token, userContributeInfo]); return ( @@ -387,23 +381,16 @@ const PrivateSaleForm = ({ vcInfo }: { vcInfo?: VCInfo }) => { {/* */} {/*)}*/} -
{renderLoginTooltip()}
+
+ { + renderLoginTooltip() + } +
- - - - {/* + - */} + {parseFloat(userContributeInfo?.usdt_value || '0') > 0 && ( From 5efa604d77c0ee0d7f44faf56c4dea8d413748ab Mon Sep 17 00:00:00 2001 From: wilfred Date: Wed, 31 Jan 2024 16:33:29 +0700 Subject: [PATCH 43/50] update --- src/stores/states/user/reducer.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/stores/states/user/reducer.ts b/src/stores/states/user/reducer.ts index 31905545a..3d5a601dc 100644 --- a/src/stores/states/user/reducer.ts +++ b/src/stores/states/user/reducer.ts @@ -1,6 +1,7 @@ import { createSlice } from '@reduxjs/toolkit'; import { EVMFieldType, UserState } from './types'; import uniqueBy from '@popperjs/core/lib/utils/uniqueBy'; +import AuthenStorage from '@/utils/storage/authen.storage'; const initialState: UserState = { user: undefined, @@ -96,6 +97,7 @@ const slice = createSlice({ }, setUserToken: (state, action) => { state.userToken = action.payload; + AuthenStorage.setAuthenKey(action.payload); }, }, }); @@ -114,7 +116,7 @@ export const { clearPublicSaleLeaderBoard, setPublicSaleLeaderBoardVisual, setGuestSecretCode, - setUserToken + setUserToken, } = slice.actions; export default slice.reducer; From f68fcddc4a885000e332999490c159806d9b17f8 Mon Sep 17 00:00:00 2001 From: camewell <130561684+camewell071@users.noreply.github.com> Date: Wed, 31 Jan 2024 16:37:53 +0700 Subject: [PATCH 44/50] chore: update ui --- src/modules/PublicSale/activities/index.tsx | 4 ++-- src/modules/PublicSale/activities/styles.module.scss | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/modules/PublicSale/activities/index.tsx b/src/modules/PublicSale/activities/index.tsx index 82ab4a782..41e9d22bd 100644 --- a/src/modules/PublicSale/activities/index.tsx +++ b/src/modules/PublicSale/activities/index.tsx @@ -261,7 +261,7 @@ Good luck and have fun! [styles.itemWrapper_title__active]: isExpanded, })} > - {item.tag}: {title} {item.key === currentDay.diffDay && (Happening Now)} + {item.key === currentDay.diffDay && Happening Now} {item.tag}: {title}
@@ -283,9 +297,9 @@ Good luck and have fun! className={styles.itemWrapper_desc} dangerouslySetInnerHTML={{ __html: item.desc }} /> - {currentDay.diffDay === expandIndex && expandIndex === item.key && item.key === 1 && ( - - )} + {currentDay.diffDay === expandIndex && + expandIndex === item.key && + item.key === 1 && } {item.ctas?.map(renderCta)} @@ -307,13 +321,21 @@ Good luck and have fun!

Experience Bitcoin like never before.

- { - setExpandIndex(expandedIndex as number) - }}> + { + setExpandIndex(expandedIndex as number); + }} + > {DAYS.map(renderItem)}
- + ); }); diff --git a/src/modules/PublicSale/activities/styles.module.scss b/src/modules/PublicSale/activities/styles.module.scss index c1a7671c3..4fb057a13 100644 --- a/src/modules/PublicSale/activities/styles.module.scss +++ b/src/modules/PublicSale/activities/styles.module.scss @@ -1,22 +1,22 @@ -.wrap{ +.wrap { overflow-y: auto; -ms-overflow-style: none; /* Internet Explorer 10+ */ scrollbar-width: none; /* Firefox */ - @include is-pc{ + @include is-pc { height: 810px; } &::-webkit-scrollbar { display: none; /* Safari and Chrome */ } - background-color: #1B1B1B; + background-color: #1b1b1b; } .container { &__title { align-self: stretch; - color: #FFFFFF; + color: #ffffff; font-size: 24px; font-style: normal; font-weight: 400; @@ -31,24 +31,24 @@ justify-content: space-between; align-items: center; align-self: stretch; - background-color: rgba(white, .06); + background-color: rgba(white, 0.06); border: 1px solid rgba(255, 255, 255, 0.06); button { padding: 12px 20px; - svg path{ - stroke: #FFFFFF !important; + svg path { + stroke: #ffffff !important; } } } - :global(.chakra-collapse){ + :global(.chakra-collapse) { padding: 10px 16px !important; padding-bottom: 0 !important; } &_title { - color: #FFFFFF; + color: #ffffff; font-size: 14px; font-weight: 500; line-height: 20px; @@ -61,11 +61,11 @@ span { color: white; - padding: 2px 4px; + padding: 4px 12px; font-size: 10px; font-weight: 400; border-radius: 100px; - background: #FA4E0E; + background: #fa4e0e; margin-right: 4px; } @@ -74,28 +74,28 @@ } &__active { - color: #FFFFFF; + color: #ffffff; //background-color: rgba(white, .08); } } &_desc { - color: rgba(white, .7); + color: rgba(white, 0.7); font-size: 14px; font-weight: 400; line-height: 20px; letter-spacing: 0em; - b, strong{ + b, + strong { color: white; } @include is-mobile { font-size: 14px; } - } &_header { padding: 10px 16px !important; - background-color: rgba(black, .8); + background-color: rgba(black, 0.8); //border: 1px solid rgba(white, .10); cursor: default !important; gap: 8px; @@ -107,7 +107,7 @@ &__active { background-color: transparent; border: 0 !important; - border-bottom: 1px solid rgba(white, .07) !important; + border-bottom: 1px solid rgba(white, 0.07) !important; button { display: block !important; @@ -119,7 +119,6 @@ // display: none !important; //} } - } &_downArrow { transform: rotate(270deg); @@ -135,7 +134,7 @@ } &_learnMore { - color: #FA4E0E; + color: #fa4e0e; text-align: center; font-size: 14px; font-style: normal; From 54e4fb4c93c021d4fe6d699312b9f00e8aaf2636 Mon Sep 17 00:00:00 2001 From: 2712 <2712@trustless.computer> Date: Wed, 31 Jan 2024 17:22:13 +0700 Subject: [PATCH 46/50] chore: update airdrop --- src/modules/airdrop/StepAirdrop/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/airdrop/StepAirdrop/index.tsx b/src/modules/airdrop/StepAirdrop/index.tsx index 721463fb7..b4da1f855 100644 --- a/src/modules/airdrop/StepAirdrop/index.tsx +++ b/src/modules/airdrop/StepAirdrop/index.tsx @@ -162,6 +162,7 @@ const StepsAirdrop = (props: IProps) => { const resGMHolders = await getBVMAirdrop({ address, + type, }); if (resGMHolders && compareString(resGMHolders.type, type)) { From b03eaa06fa1e0deca309ae33ce6d0bde32d8d1b8 Mon Sep 17 00:00:00 2001 From: camewell <130561684+camewell071@users.noreply.github.com> Date: Wed, 31 Jan 2024 17:29:29 +0700 Subject: [PATCH 47/50] chore: update ui --- src/components/BaseModal/styles.module.scss | 2 +- src/modules/PublicSale/AuthForBuyV2/index.tsx | 469 ++++++++++++------ src/modules/PublicSale/BuyForm/index.tsx | 10 + src/modules/Whitelist/FAQContent/index.tsx | 12 +- src/services/public-sale.ts | 12 + src/stores/states/user/selector.ts | 3 +- src/utils/metamask-helper.ts | 7 +- 7 files changed, 353 insertions(+), 162 deletions(-) diff --git a/src/components/BaseModal/styles.module.scss b/src/components/BaseModal/styles.module.scss index a017af630..00945262f 100644 --- a/src/components/BaseModal/styles.module.scss +++ b/src/components/BaseModal/styles.module.scss @@ -38,7 +38,7 @@ background-color: transparent !important; position: absolute; right: 0; - top: 0; + top: -2px; &:focus-visible { outline: none; } diff --git a/src/modules/PublicSale/AuthForBuyV2/index.tsx b/src/modules/PublicSale/AuthForBuyV2/index.tsx index 0b57ed33d..f6986672a 100644 --- a/src/modules/PublicSale/AuthForBuyV2/index.tsx +++ b/src/modules/PublicSale/AuthForBuyV2/index.tsx @@ -1,10 +1,25 @@ -import { userTokenSelector } from '@/stores/states/user/selector'; +import { userSelector, userTokenSelector } from '@/stores/states/user/selector'; import { Button, Flex, Text, Tooltip, useDisclosure } from '@chakra-ui/react'; import cx from 'classnames'; -import React, { PropsWithChildren, useMemo } from 'react'; -import { useSelector } from 'react-redux'; +import React, { PropsWithChildren, useEffect, useMemo, useRef, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; import s from './styles.module.scss'; import BaseModal from '@/components/BaseModal'; +import { IAuthenCode } from '@/modules/Whitelist/steps'; +import { getLink, getUuid } from '@/utils/helpers'; +import { generateTokenWithTwPost, requestAuthenByShareCode } from '@/services/player-share'; +import AuthenStorage from '@/utils/storage/authen.storage'; +import { setBearerToken } from '@/services/whitelist'; +import { requestReload } from '@/stores/states/common/reducer'; +import { generateTokenWithMetamask, generateTokenWithOauth, getPublicSaleSummary } from '@/services/public-sale'; +import { BVM_API, TWITTER_CLIENT_ID } from '@/config'; +import { formatCurrency } from '@/utils/format'; +import { useAppSelector } from '@/stores/hooks'; +import { setUserToken } from '@/stores/states/user/reducer'; +import AppLoading from '@/components/AppLoading'; +import { getError } from '@/utils/error'; +import toast from 'react-hot-toast'; +import { signMessage } from '@/utils/metamask-helper'; interface IAuthForBuyV2 extends PropsWithChildren { renderWithoutLogin?: (onClick: any) => any; @@ -14,12 +29,159 @@ const AuthForBuyV2: React.FC = ({ children, renderWithoutLogin, }) => { + const user = useAppSelector(userSelector); + const [authenCode, setAuthenCode] = useState(); + const timer = useRef(); + const [submitting, setSubmitting] = useState(false); + const dispatch = useDispatch(); + const [isCopy, setIsCopy] = useState(false); + const uuid = getUuid(); + const userToken = useSelector(userTokenSelector); const isLogged = useMemo(() => Boolean(userToken), [userToken]); const { isOpen, onOpen, onClose } = useDisclosure(); + useEffect(() => { + if (authenCode?.public_code) { + setSubmitting(true); + timer.current = setInterval(async () => { + handleVerifyTwitter(); + }, 5000); + } + return () => { + clearInterval(timer.current); + }; + }, [authenCode?.public_code]); + + const handleVerifyTwitter = async (): Promise => { + try { + const result = await generateTokenWithTwPost( + authenCode?.secret_code as string, + ); + onVerifyTwSuccess(result); + } catch (err) { + console.log('handleVerifyTwitter', err); + } + }; + + const onVerifyTwSuccess = (result: any) => { + if (result) { + clearInterval(timer.current); + const twitterToken = AuthenStorage.getAuthenKey(); + if (!twitterToken || twitterToken !== result?.token) { + AuthenStorage.setAuthenKey(result?.token); + setBearerToken(result?.token); + dispatch(setUserToken(result?.token)) + } + setSubmitting(false); + dispatch(requestReload()); + onClose(); + } + }; + + useEffect(() => { + if (!user?.twitter_id) { + handleVerifyTwitterWithUUID(); + timer.current = setInterval(async () => { + handleVerifyTwitterWithUUID(); + }, 2000); + } + return () => { + clearInterval(timer.current); + }; + }, [user]); + + const handleVerifyTwitterWithUUID = async (): Promise => { + try { + const result = await generateTokenWithOauth(uuid); + if (result) { + clearInterval(timer.current); + if (!userToken || userToken !== result?.token) { + onVerifyTwSuccess(result); + } + } + } catch (e) { + console.log('handleVerifyTwitter TwitterSignIn', e); + } + }; + + const getTwitterOauthUrl = () => { + const URL = `${window.location.origin}/public-sale`; + const rootUrl = 'https://twitter.com/i/oauth2/authorize'; + const options = { + redirect_uri: `${BVM_API}/twitter-api/oauth/twitter-bvm?callbackURL=${URL}&uuid=${uuid}`, + client_id: TWITTER_CLIENT_ID, + state: 'state', + response_type: 'code', + code_challenge: 'challenge', + code_challenge_method: 'plain', + scope: [ + 'users.read', + 'tweet.read', + 'follows.read', + 'offline.access', + ].join(' '), + }; + const qs = new URLSearchParams(options).toString(); + setTimeout(() => window.open(`${rootUrl}?${qs}`, '_self')) + }; + + const generateLinkTweet = async () => { + let code = ''; + if (!userToken) { + const res: any = await requestAuthenByShareCode(); + setAuthenCode(res); + code = `\n\n#${res?.public_code}`; + } + + const shareUrl = !user?.referral_code + ? 'bvm.network/public-sale' + : getLink(user?.referral_code || ''); + + const saleSummary = await getPublicSaleSummary(); + const content = `Welcome to the future of Bitcoin!\n\n@BVMnetwork is the first modular blockchain metaprotocol that lets you launch your Bitcoin L2 blockchain in a few clicks.\n\nJoin the ${formatCurrency( + saleSummary.total_user || '0', + 0, + 0, + 'BTC', + false, + )} early contributors backing us with ${formatCurrency( + saleSummary.total_usdt_value_not_boost || '0', + 0, + 0, + 'BTC', + false, + )} to build the future of Bitcoin.${code}`; + return `https://twitter.com/intent/tweet?url=${shareUrl}&text=${encodeURIComponent( + content, + )}`; + }; + + const handleShareTw = async () => { + setIsCopy(false); + const content = await generateLinkTweet(); + setTimeout(() => window.open(content, '_blank')) + }; + + const handleLoginMetamask = async () => { + try { + const { signature, message, address } = await signMessage((address: string) => { + return `This action verifies the ownership of ${address} and allows you to join the $BVM public sale.` + }) + const result = await generateTokenWithMetamask({ message, signature, address }) + if (result && !!result.token) { + AuthenStorage.setAuthenKey(result.token as string); + setBearerToken(result.token as string); + dispatch(setUserToken(result.token as string)) + } + } catch (error) { + const { message } = getError(error) + toast.error(message) + } + } + if (isLogged) { return children; } @@ -35,159 +197,162 @@ const AuthForBuyV2: React.FC = ({ onHide={onClose} className={s.loginModal} > - - + - + + + + + + + + + + + + + + Connect your Metamask + + ); diff --git a/src/modules/PublicSale/BuyForm/index.tsx b/src/modules/PublicSale/BuyForm/index.tsx index 81ef64661..d6de10622 100644 --- a/src/modules/PublicSale/BuyForm/index.tsx +++ b/src/modules/PublicSale/BuyForm/index.tsx @@ -26,6 +26,8 @@ import { GuestCodeHere } from '../depositModal/deposit.guest.code'; import LoginTooltip from '@/modules/PublicSale/depositModal/login.tooltip'; import { useAppSelector } from '@/stores/hooks'; import { commonSelector } from '@/stores/states/common/selector'; +import IcHelp from '@/components/InfoTooltip/IcHelp'; +import AuthForBuyV2 from '@/modules/PublicSale/AuthForBuyV2'; interface FormValues { tokenAmount: string; @@ -178,6 +180,14 @@ const PrivateSaleForm = ({ vcInfo }: { vcInfo?: VCInfo }) => { gap={1} alignItems={"center"} > Your contribution + ( + + + + )}> + + { }}/> diff --git a/src/modules/Whitelist/FAQContent/index.tsx b/src/modules/Whitelist/FAQContent/index.tsx index 7eb7fb6d1..ddef2a8d8 100644 --- a/src/modules/Whitelist/FAQContent/index.tsx +++ b/src/modules/Whitelist/FAQContent/index.tsx @@ -3,7 +3,7 @@ import { Accordion, AccordionItem, AccordionButton, - AccordionPanel, + AccordionPanel, Button, } from '@chakra-ui/react'; import s from './styles.module.scss'; import { CDN_URL } from '@/config'; @@ -15,6 +15,7 @@ import { compareString } from '@/utils/string'; import DepositGuestCodeHere from '@/modules/PublicSale/depositModal/deposit.guest.code'; import { GoogleReCaptchaProvider } from 'react-google-recaptcha-v3'; import AuthenStorage from '@/utils/storage/authen.storage'; +import AuthForBuyV2 from '@/modules/PublicSale/AuthForBuyV2'; const FAQContent: React.FC = (): React.ReactElement => { const user = useAppSelector(userSelector); @@ -232,9 +233,12 @@ const FAQContent: React.FC = (): React.ReactElement => { ) : (

If you have a boost,{' '} - - claim it here - + + ( + claim it here + )}> + .

)} diff --git a/src/services/public-sale.ts b/src/services/public-sale.ts index 9ba0b93c5..6ca208fa2 100644 --- a/src/services/public-sale.ts +++ b/src/services/public-sale.ts @@ -67,6 +67,18 @@ export const generateTokenWithOauth = async ( return res; }; +export const generateTokenWithMetamask = async ( + params: { address: string, message: string, signature: string } +): Promise => { + const res = (await apiClient.post(`/bvm/generate-token-with-wallet`, { + "wallet_type": "ethereum", + "address": params.address, + "message": params.message, + "signature": params.signature + })) as unknown as IGenerateTOkenWithSecretCode; + return res; +}; + export const getPublicSaleLeaderBoards = async (params: { page?: number; limit?: number; diff --git a/src/stores/states/user/selector.ts b/src/stores/states/user/selector.ts index 13df04199..25931b9cb 100644 --- a/src/stores/states/user/selector.ts +++ b/src/stores/states/user/selector.ts @@ -2,10 +2,11 @@ import { RootState } from '@/stores'; import { EVMFieldType, User } from '@/stores/states/user/types'; import { ILeaderBoardPoint } from '@/interfaces/leader-board-point'; import { SignatureStatus } from '@/interfaces/whitelist'; +import AuthenStorage from '@/utils/storage/authen.storage'; export const userSelector = (state: RootState) => state.user?.user as User | undefined; -export const userTokenSelector = (state: RootState) => state.user?.userToken; +export const userTokenSelector = (state: RootState) => state.user?.userToken || AuthenStorage.getAuthenKey() || AuthenStorage.getGuestAuthenKey(); export const leaderBoardSelector = (state: RootState) => ({ list: (state.user?.leaderBoard || []) as ILeaderBoardPoint[], count: (state.user?.leaderBoardCount || '') as string, diff --git a/src/utils/metamask-helper.ts b/src/utils/metamask-helper.ts index 18192e07c..c9dd9f541 100644 --- a/src/utils/metamask-helper.ts +++ b/src/utils/metamask-helper.ts @@ -119,13 +119,12 @@ export const signMessage = async (message: any): Promise<{ message: string, addr const signer = web3Provider.getSigner(); const address = addresses && Array.isArray(addresses) ? addresses[0] : ''; - const signature = await signer.signMessage( - typeof message === 'function' ? message(address) : message, - ); + const messageForSign = typeof message === 'function' ? message(address) : message; + const signature = await signer.signMessage(messageForSign); return { address, signature, - message, + message: messageForSign, }; } catch (err) { throw err; From b9951bee0a74a8476e4a3a7220d88c4586dcefd3 Mon Sep 17 00:00:00 2001 From: camewell <130561684+camewell071@users.noreply.github.com> Date: Wed, 31 Jan 2024 17:39:51 +0700 Subject: [PATCH 48/50] chore: login v3 --- src/modules/PublicSale/AuthForBuyV2/index.tsx | 85 +++++++++++++------ src/modules/PublicSale/BuyForm/index.tsx | 4 +- 2 files changed, 59 insertions(+), 30 deletions(-) diff --git a/src/modules/PublicSale/AuthForBuyV2/index.tsx b/src/modules/PublicSale/AuthForBuyV2/index.tsx index f6986672a..4d610bba1 100644 --- a/src/modules/PublicSale/AuthForBuyV2/index.tsx +++ b/src/modules/PublicSale/AuthForBuyV2/index.tsx @@ -20,6 +20,7 @@ import AppLoading from '@/components/AppLoading'; import { getError } from '@/utils/error'; import toast from 'react-hot-toast'; import { signMessage } from '@/utils/metamask-helper'; +import VerifyTwModal from '@/modules/Whitelist/steps/VerifyTwModal'; interface IAuthForBuyV2 extends PropsWithChildren { renderWithoutLogin?: (onClick: any) => any; @@ -36,6 +37,8 @@ const AuthForBuyV2: React.FC = ({ const dispatch = useDispatch(); const [isCopy, setIsCopy] = useState(false); const uuid = getUuid(); + const [showManualCheck, setShowManualCheck] = useState(false); + const [showManualCheckModal, setShowManualCheckModal] = useState(false); const userToken = useSelector(userTokenSelector); @@ -162,7 +165,10 @@ const AuthForBuyV2: React.FC = ({ const handleShareTw = async () => { setIsCopy(false); const content = await generateLinkTweet(); - setTimeout(() => window.open(content, '_blank')) + setTimeout(() => window.open(content, '_blank')); + setTimeout(() => { + setShowManualCheck(true); + }, 10000); }; const handleLoginMetamask = async () => { @@ -199,34 +205,48 @@ const AuthForBuyV2: React.FC = ({ > {submitting && } - + + + + + + + + Post on X + + {showManualCheck && ( + setShowManualCheckModal(true)} + mt={1} + fontSize={'12px !important'} + mb="12px" + > + Can't link account? + + )} + + { + setShowManualCheckModal(false); + }} + secretCode={authenCode?.secret_code} + onSuccess={onVerifyTwSuccess} + title={`Can't link account?`} + /> ); } diff --git a/src/modules/PublicSale/BuyForm/index.tsx b/src/modules/PublicSale/BuyForm/index.tsx index d6de10622..f10288975 100644 --- a/src/modules/PublicSale/BuyForm/index.tsx +++ b/src/modules/PublicSale/BuyForm/index.tsx @@ -188,9 +188,9 @@ const PrivateSaleForm = ({ vcInfo }: { vcInfo?: VCInfo }) => { )}> - { + {/* {*/} - }}/> + {/*}}/>*/} From c7365715ba8ca876b778f43a8617b940420d9871 Mon Sep 17 00:00:00 2001 From: camewell <130561684+camewell071@users.noreply.github.com> Date: Wed, 31 Jan 2024 17:44:31 +0700 Subject: [PATCH 49/50] chore: update ui --- src/modules/PublicSale/BuyForm/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/PublicSale/BuyForm/index.tsx b/src/modules/PublicSale/BuyForm/index.tsx index f10288975..ba94ea36b 100644 --- a/src/modules/PublicSale/BuyForm/index.tsx +++ b/src/modules/PublicSale/BuyForm/index.tsx @@ -182,7 +182,7 @@ const PrivateSaleForm = ({ vcInfo }: { vcInfo?: VCInfo }) => { Your contribution ( - + )}> From 493d7bae4bc4c1edf0b2e07c271ff8945dc94729 Mon Sep 17 00:00:00 2001 From: camewell <130561684+camewell071@users.noreply.github.com> Date: Wed, 31 Jan 2024 17:46:11 +0700 Subject: [PATCH 50/50] chore: update code --- src/utils/metamask-helper.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/utils/metamask-helper.ts b/src/utils/metamask-helper.ts index c9dd9f541..83d804b8d 100644 --- a/src/utils/metamask-helper.ts +++ b/src/utils/metamask-helper.ts @@ -105,15 +105,16 @@ const connect = async (): Promise> => { export const signMessage = async (message: any): Promise<{ message: string, address: string, signature: string }> => { try { - if (!(window as any).ethereum) { - throw Error(WalletError.NO_INSTANCE); - } if (!isMetamaskInstalled()) { window.open(METAMASK_DOWNLOAD_PAGE); throw Error(WalletError.NO_METAMASK); } + if (!(window as any).ethereum) { + throw Error(WalletError.NO_INSTANCE); + } + const web3Provider = new ethers.providers.Web3Provider((window as any).ethereum); const addresses = await web3Provider.send('eth_requestAccounts', []); const signer = web3Provider.getSigner();