diff --git a/src/api/index.ts b/src/api/index.ts index c83f4aef..65033954 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -738,6 +738,9 @@ export const getCategoryList = ( export const dailyOpen = (): Promise => http.post(`${BASE_URL_API}/invite/checkin/open`); +export const dailySkipMint = (): Promise => + http.post(`${BASE_URL_API}/invite/skip`); + export interface DailyCheckinHistoryData { date: string; expired: boolean; diff --git a/src/components/DashboardS2/DailyRoulette/DailyDrawModal.tsx b/src/components/DashboardS2/DailyRoulette/DailyDrawModal.tsx index 87ff8c1c..75c299ec 100644 --- a/src/components/DashboardS2/DailyRoulette/DailyDrawModal.tsx +++ b/src/components/DashboardS2/DailyRoulette/DailyDrawModal.tsx @@ -12,9 +12,12 @@ import { import { UseDisclosureReturn } from "@nextui-org/use-disclosure"; import Marquee from "@/components/Marquee"; import { useRef, useState, useEffect, useCallback, useMemo } from "react"; -import { dailyOpen } from "@/api"; +import { dailyOpen, dailySkipMint } from "@/api"; import { sleep } from "@/utils"; -import useNovaNFT, { MysteryboxMintParams } from "@/hooks/useNovaNFT"; +import useNovaNFT, { + MysteryboxMintParams, + TrademarkMintParams, +} from "@/hooks/useNovaNFT"; import { MintStatus, TRADEMARK_NFT_MARKET_URL, @@ -22,6 +25,8 @@ import { } from "@/constants"; import { TxResult } from "@/components/Dashboard/NovaCharacter"; import { useAccount, useSwitchChain } from "wagmi"; +import { useUpdateNftBalanceStore } from "@/hooks/useUpdateNftBalanceStore"; + interface IProps { modalInstance: UseDisclosureReturn; onDrawed: () => void; @@ -69,6 +74,7 @@ const DailyDrawModal: React.FC = (props: IProps) => { const [mintStatus, setMintStatus] = useState(); const [failMessage, setFailMessage] = useState(""); const { switchChain } = useSwitchChain(); + const { updateFactor } = useUpdateNftBalanceStore(); const { sendTrademarkMintTx } = useNovaNFT(); const { modalInstance, onDrawed, remain } = props; @@ -79,6 +85,7 @@ const DailyDrawModal: React.FC = (props: IProps) => { points?: number; tooltip?: string; }>(); + const [mintParams, setMintParams] = useState(); const mintResultModal = useDisclosure(); const handleDrawEnd = () => {}; @@ -112,9 +119,7 @@ const DailyDrawModal: React.FC = (props: IProps) => { setMintResult({ ...prize, }); - if ([1, 2, 3, 4].includes(tokenId)) { - await sleep(2000); // show nft - setMinting(true); + if (tokenId <= 4) { const { tokenId, nonce, signature, expiry, mintType } = res.result; const mintParams = { tokenId, @@ -124,32 +129,12 @@ const DailyDrawModal: React.FC = (props: IProps) => { method: "safeMintCommon", mintType, }; - - try { - await sendTrademarkMintTx(mintParams); - setMintStatus(MintStatus.Success); - mintResultModal.onOpen(); - onDrawed(); // update remain times after mint tx - } catch (e) { - console.log(e); - setMintStatus(MintStatus.Failed); - if (e.message) { - if (e.message.includes("rejected the request")) { - setFailMessage("User rejected the request"); - } else { - setFailMessage(e.message); - } - } - } finally { - setMinting(false); - setSpinging(false); - } + setMintParams(mintParams); } else { setMintStatus(MintStatus.Success); mintResultModal.onOpen(); - setSpinging(false); } - + setSpinging(false); if (!remain || remain <= 1) { modalInstance.onClose(); } @@ -160,10 +145,49 @@ const DailyDrawModal: React.FC = (props: IProps) => { modalInstance, onDrawed, remain, - sendTrademarkMintTx, switchChain, ]); + const handleMint = useCallback(async () => { + if (!mintParams) { + return; + } + try { + setMinting(true); + await sendTrademarkMintTx(mintParams); + setMintStatus(MintStatus.Success); + mintResultModal.onOpen(); + onDrawed(); // update remain times after mint tx + setMintParams(undefined); + updateFactor(); + } catch (e) { + console.log(e); + setMintStatus(MintStatus.Failed); + if (e.message) { + if (e.message.includes("rejected the request")) { + setFailMessage("User rejected the request"); + } else { + setFailMessage(e.message); + } + } + } finally { + setMinting(false); + } + }, [ + mintParams, + mintResultModal, + onDrawed, + sendTrademarkMintTx, + updateFactor, + ]); + + const handleSkip = async () => { + await dailySkipMint(); + setMintParams(undefined); + mintResultModal.onClose(); + onDrawed(); // update remain times after skip + }; + useEffect(() => { if (!modalInstance.isOpen) { setMinting(false); @@ -210,29 +234,55 @@ const DailyDrawModal: React.FC = (props: IProps) => { ref={drawRef} onDrawEnd={handleDrawEnd} PrizeItems={PrizeItems} + targetIndex={ + mintParams ? PRIZE_MAP[mintParams.tokenId] : undefined + } /> -
- - - {btnText} - -
+ {!mintParams && ( +
+ + + {btnText} + +
+ )} + {mintParams && ( +
+ + Skip + + + {!minting && ( + + )} + Mint + +
+ )}
)} diff --git a/src/components/DashboardS2/Tabs/PortfolioComponents/LynksNFT.tsx b/src/components/DashboardS2/Tabs/PortfolioComponents/LynksNFT.tsx index 6b1c4977..bf505194 100644 --- a/src/components/DashboardS2/Tabs/PortfolioComponents/LynksNFT.tsx +++ b/src/components/DashboardS2/Tabs/PortfolioComponents/LynksNFT.tsx @@ -6,15 +6,17 @@ import { useAccount } from "wagmi"; import { useState, useEffect, useCallback, useMemo } from "react"; import { Abi } from "viem"; import SbtUpgradeModal from "@/components/Dashboard/NovaCharacterComponents/SbtUpgradeModal"; +import { useUpdateNftBalanceStore } from "@/hooks/useUpdateNftBalanceStore"; + export default function SbtNFT() { const { address } = useAccount(); const [lynksBalance, setLynksBalance] = useState(0); const { publicClient, trademarkNFT } = useNovaNFT(); const { getLynksNFT } = useNovaNFT(); const { nft, loading: mintLoading, fetchLoading } = useSbtNft(); - const [update, setUpdate] = useState(0); const upgradeModal = useDisclosure(); const [upgradable, setUpgradable] = useState(false); + const { factor, updateFactor } = useUpdateNftBalanceStore(); useEffect(() => { (async () => { @@ -45,7 +47,7 @@ export default function SbtNFT() { } } })(); - }, [address, getLynksNFT, publicClient, trademarkNFT, update]); + }, [address, getLynksNFT, publicClient, trademarkNFT, factor]); useEffect(() => { (async () => { @@ -61,7 +63,7 @@ export default function SbtNFT() { setLynksBalance(balance); } })(); - }, [address, getLynksNFT]); + }, [address, getLynksNFT, factor]); const handleMintNow = useCallback(() => { if (fetchLoading) { @@ -108,7 +110,9 @@ export default function SbtNFT() { nft={nft} mintLoading={mintLoading} upgradeModal={upgradeModal} - onUpgraded={() => setUpdate((v) => v + 1)} + onUpgraded={() => { + updateFactor(); + }} /> ); diff --git a/src/components/DashboardS2/Tabs/PortfolioComponents/TrademarkNFT.tsx b/src/components/DashboardS2/Tabs/PortfolioComponents/TrademarkNFT.tsx index f80e182d..5478e4dd 100644 --- a/src/components/DashboardS2/Tabs/PortfolioComponents/TrademarkNFT.tsx +++ b/src/components/DashboardS2/Tabs/PortfolioComponents/TrademarkNFT.tsx @@ -3,7 +3,7 @@ import useNovaNFT, { MysteryboxMintParams } from "@/hooks/useNovaNFT"; import { useAccount } from "wagmi"; import { Abi } from "viem"; import styled from "styled-components"; - +import { useUpdateNftBalanceStore } from "@/hooks/useUpdateNftBalanceStore"; const Container = styled.div` margin-top: 20px; & > div:last-child { @@ -88,7 +88,7 @@ export default function TrademarkNFT() { const [nftData, setNftData] = useState(ALL_NFTS); const { address } = useAccount(); const { publicClient, trademarkNFT } = useNovaNFT(); - + const { factor } = useUpdateNftBalanceStore(); useEffect(() => { (async () => { if (!publicClient || !address || !trademarkNFT) { @@ -112,7 +112,7 @@ export default function TrademarkNFT() { } setNftData(nfts); })(); - }, [address, publicClient, trademarkNFT]); + }, [address, publicClient, trademarkNFT, factor]); return ( diff --git a/src/components/Marquee/index.tsx b/src/components/Marquee/index.tsx index 08bcee34..6cae9bf6 100644 --- a/src/components/Marquee/index.tsx +++ b/src/components/Marquee/index.tsx @@ -89,7 +89,8 @@ const Marquee = forwardRef((props, ref) => { useEffect(() => { if (marqueeRef.current) { marqueeRef.current.style.transform = `translateX(${ - Math.floor(PrizeItems.length / 2) * IMAGE_WIDTH + Math.floor(PrizeItems.length / 2) * IMAGE_WIDTH - + (targetIndex ?? 0) * IMAGE_WIDTH }px)`; } }, []); diff --git a/src/hooks/useUpdateNftBalanceStore.ts b/src/hooks/useUpdateNftBalanceStore.ts new file mode 100644 index 00000000..07ecb547 --- /dev/null +++ b/src/hooks/useUpdateNftBalanceStore.ts @@ -0,0 +1,13 @@ +import { create } from "zustand"; + +interface UpdateNftBalanceStore { + factor: number; + updateFactor: () => void; +} + +export const useUpdateNftBalanceStore = create( + (set) => ({ + factor: 0, + updateFactor: () => set((state) => ({ factor: state.factor + 1 })), + }) +);