Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add buy maze match #112

Open
wants to merge 25 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
8218a8b
WIP creating new buy interface
Mart-Dan-Rossi Nov 21, 2024
d125819
WIP modify Buy button on maze
Mart-Dan-Rossi Nov 22, 2024
ba9be9b
Visual aspects finished
Mart-Dan-Rossi Nov 22, 2024
8d334f8
Add purchase button
Mart-Dan-Rossi Nov 22, 2024
d80252b
Choose Tabs variant line
Mart-Dan-Rossi Nov 22, 2024
7062807
Minor styles changes
Mart-Dan-Rossi Nov 22, 2024
ed6e9f2
Add moked query to call matchsAmountLefts
Mart-Dan-Rossi Nov 22, 2024
c2036a3
Add moked query to call cheddarMazeMatchBuyPrice
Mart-Dan-Rossi Nov 22, 2024
2bed5a6
Change styles
Mart-Dan-Rossi Nov 25, 2024
72ac45d
[WIP] integrate backend
Mart-Dan-Rossi Nov 28, 2024
b149bef
[WIP] integrate comunication with backend to buy matches
Mart-Dan-Rossi Nov 28, 2024
2085d05
[WIP] getting seedId from back
Mart-Dan-Rossi Nov 30, 2024
5283961
Show toast when buying matchs with myNearWallet
Mart-Dan-Rossi Dec 2, 2024
0236770
[WIP] handle myNearWallet redirections
Mart-Dan-Rossi Dec 3, 2024
70c62b7
[WIP] Handle start game
Mart-Dan-Rossi Dec 4, 2024
3d5ce3f
[WIP] implementing lose_game call
Mart-Dan-Rossi Dec 5, 2024
b5a2a1f
Fix myNearWallet loop on restartGame()
Mart-Dan-Rossi Dec 9, 2024
9a8b6e1
Call lose_game when losing in near blockchain
Mart-Dan-Rossi Dec 10, 2024
1e7ed6c
Run prettier
Mart-Dan-Rossi Dec 10, 2024
4c3b614
[WIP] merge done. Fixing callLoseGame
Mart-Dan-Rossi Dec 12, 2024
6f97ec2
Merge with dev (Megha changes)
Mart-Dan-Rossi Dec 12, 2024
439803e
Fix swapNearToCheddar bad import in ModalBuyCheddarRed.tsx
Mart-Dan-Rossi Dec 12, 2024
42f8345
Stop calling unused props in GameboardContainer
Mart-Dan-Rossi Dec 12, 2024
4359533
Wait till swap compleated to show success toast
Mart-Dan-Rossi Dec 13, 2024
e0f1acd
Fix redirection on lose_game call
Mart-Dan-Rossi Dec 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import OnchainContextProvider from '@/contexts/OnchainContextProvider';
import WagmiContextProvider from '@/contexts/WagmiContextProvider';
import { GlobalContextProvider } from '@/contexts/GlobalContext';
import { getConfig } from '@/configs/config';
import { useEffect } from 'react';

const inter = Inter({ subsets: ['latin'] });

Expand Down
196 changes: 196 additions & 0 deletions src/components/BuyMatchTab.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
import styles from '@/styles/BuyMatchTab.module.css';

import { getConfig } from '@/configs/config';
import {
useGlobalContext
} from '@/contexts/GlobalContext';
import { useWalletSelector } from '@/contexts/WalletSelectorContext';
import { yton } from '@/contracts/contractUtils';
import { ftTransferCall } from '@/contracts/tokenCheddarCalls';
import { useGetCheddarMazeMatchPrices } from '@/hooks/maze';
import { addEncodedDataToURL } from '@/utilities/exportableFunctions';
import { InfoOutlineIcon } from '@chakra-ui/icons';
import {
Button,
Flex,
Input,
InputGroup,
InputLeftElement,
InputRightElement,
NumberDecrementStepper,
NumberIncrementStepper,
NumberInput,
NumberInputField,
NumberInputStepper,
Spinner,
useToast,
} from '@chakra-ui/react';
import { useState } from 'react';
import { RenderCheddarIcon } from './maze/RenderCheddarIcon';

interface Props {}

export const BuyMatchTab = ({}: Props) => {
const { data: options, isLoading: isOptionsLoading } =
useGetCheddarMazeMatchPrices();

const toast = useToast();

const { blockchain } = useGlobalContext();

const { selector } = useWalletSelector();

const [amountToBuy, setAmountToBuy] = useState<number>(1);

const [isLoading, setIsLoading] = useState(false);

function getOptionStyles(index: number) {
return `${styles.option} ${index !== 0 && styles.borderLeft}`;
}

function getTotalPrice() {
const option =
options &&
options
.slice()
.reverse()
.find((o: any /*Change type to propper one*/) => amountToBuy >= o[0]);

return `${option ? (amountToBuy * yton(option[1])).toFixed(1) : 0}`;
}

async function handleBuyMatches() {
if (blockchain !== 'near') return;

addEncodedDataToURL(blockchain, 'buyMazeMatch', 'buying maze match');

try {
setIsLoading(true);
const wallet = await selector.wallet();
const amount = getTotalPrice();

const mazeBuyerContract = getConfig().contracts.near.mazeBuyer;
const cheddarContract = getConfig().contracts.near.cheddarToken;

const response = await ftTransferCall(
wallet,
cheddarContract,
mazeBuyerContract,
Number(amount)
);

if (yton(response) >= 0) {
toast({
title: 'Successful purchase',
status: 'success',
duration: 9000,
position: 'bottom-right',
isClosable: true,
});
}
} catch (err: any) {
toast({
title: err.message,
status: 'error',
duration: 9000,
position: 'bottom-right',
isClosable: true,
});
}
setIsLoading(false);
}

return (
<div>
<Flex className={styles.generalContainer} align={'center'}>
<InfoOutlineIcon height={'20px'} width={'20px'} color={'white'} />
<Flex direction={'column'} marginLeft={'1rem'} color={'white'}>
<span className={styles.discountsTitle}>Game discounts!</span>
{isOptionsLoading ? (
<Spinner />
) : (
options &&
options.map((option: any, index: number) => {
if (index > 0) {
return (
<>
<span>
+ {option[0]} games = {yton(option[1])}{' '}
<RenderCheddarIcon /> each
</span>
</>
);
} else {
return <></>;
}
})
)}
</Flex>
</Flex>
<Flex className={styles.selectAmountContainer}>
<Flex className={styles.amountOptionsSelector}>
{isOptionsLoading ? (
<Spinner />
) : (
options &&
options.map((option: any, index: number) => {
return (
<span
key={`buy-match-option-selector-${index}`}
className={getOptionStyles(index)}
onClick={() => setAmountToBuy(Number(option[0]))}
>
{option[0]}
</span>
);
})
)}
</Flex>
<NumberInput
width={'70px'}
defaultValue={1}
value={amountToBuy}
onChange={(e) => setAmountToBuy(Number(e))}
>
<NumberInputField />
<NumberInputStepper>
<NumberIncrementStepper />
<NumberDecrementStepper />
</NumberInputStepper>
</NumberInput>
</Flex>
<Flex className={styles.totalPrizeContainer}>
<InputGroup className={styles.totalPrizeInput}>
<InputLeftElement
pointerEvents="none"
color="gray.300"
fontSize="1.2em"
width={'max-content'}
marginLeft={'1rem'}
>
Total price
</InputLeftElement>
<Input
textAlign={'end'}
disabled
_disabled={{
cursor: 'default',
}}
value={getTotalPrice()}
/>
<InputRightElement>
<RenderCheddarIcon />
</InputRightElement>
</InputGroup>
</Flex>
<Button
className={styles.purchaseButton}
colorScheme="yellow"
onClick={handleBuyMatches}
isLoading={isLoading}
>
Purchase
</Button>
</div>
);
};
38 changes: 19 additions & 19 deletions src/components/ModalBuyNFT.tsx → src/components/BuyNFTTab.tsx
Original file line number Diff line number Diff line change
@@ -1,43 +1,43 @@
import { getConfig } from '@/configs/config';
import {
FormControl,
FormLabel,
Button,
useToast,
Image,
VStack,
Text,
Stack,
Switch,
useToast,
} from '@chakra-ui/react';
import { ModalContainer } from './ModalContainer';
import { useWalletSelector } from '@/contexts/WalletSelectorContext';
import { RadioButtonBroup } from './maze/RadioButtonGroup';
import { useEffect, useMemo, useState } from 'react';
import { RenderCheddarIcon } from './maze/RenderCheddarIcon';
import { RenderNearIcon } from './maze/RenderNearIcon';
import { buyNFT } from '@/contracts/cheddarCalls';

import styles from '@/styles/BuyNFTSection.module.css';
import {
useGetCheddarNFTPrice,
useGetNFTCheddarBalance,
} from '@/hooks/cheddar';
import { useGetCheddarNFTPrice, useGetNFTCheddarBalance } from '@/hooks/cheddar';
import { yton } from '@/contracts/contractUtils';
import { getTransactionLastResult } from 'near-api-js/lib/providers';
import { buyNFT } from '@/contracts/tokenCheddarCalls';
import { MintNFTLastResult } from '@/entities/interfaces';
import { getConfig } from '@/configs/config';

interface Props {
onClose: () => void;
isOpen: boolean;
}

export const ModalBuyNFT = ({ isOpen, onClose }: Props) => {
export const BuyNFTTab = ({ isOpen }: Props) => {
const [isLoading, setIsLoading] = useState(false);

const { selector } = useWalletSelector();

const { nftImageBaseUrl } = getConfig().networkData;
const [nftId, setNftId] = useState('');
const [showNftImage, setShowNftImage] = useState(true);
const [isLoading, setIsLoading] = useState(false);
const { selector } = useWalletSelector();

const toast = useToast();

const {
data: cheddarNftPriceInCheddar,
isLoading: isNftPriceInCheddarLoading,
Expand All @@ -58,7 +58,6 @@ export const ModalBuyNFT = ({ isOpen, onClose }: Props) => {
}
}, [cheddarNftPriceInCheddar, nftCheddarBalance]);

const toast = useToast();

//The first option is the default one
const payingOptions = [
Expand Down Expand Up @@ -91,10 +90,11 @@ export const ModalBuyNFT = ({ isOpen, onClose }: Props) => {
}
}

async function handleBuy() {
async function handleBuyNFT() {
try {
setIsLoading(true);
const wallet = await selector.wallet();

const withCheddar = tokenToPayWith === 'Cheddar';
const amount = withCheddar
? nftRemainingCheddarToPay
Expand Down Expand Up @@ -134,7 +134,7 @@ export const ModalBuyNFT = ({ isOpen, onClose }: Props) => {
}, [isOpen]);

return (
<ModalContainer title="Buy Cheddar NFT" onClose={onClose} isOpen={isOpen}>
<>
{nftId ? (
<VStack>
<Text>NFT Minted Succesfully!</Text>
Expand Down Expand Up @@ -167,23 +167,23 @@ export const ModalBuyNFT = ({ isOpen, onClose }: Props) => {
{payingOptions.map((option, index) => {
if (option.name === tokenToPayWith) {
return (
<div key={index}>
<div key={`payingOption-${index}`}>
{`Cost: ${option.price}`} {option.icon}
</div>
);
}
return <></>;
return <div key={`payingOption-${index}`}></div>;
})}
</FormLabel>
<Button
colorScheme="yellow"
onClick={handleBuy}
onClick={handleBuyNFT}
isLoading={isLoading}
>
Purchase
</Button>
</form>
)}
</ModalContainer>
</>
);
};
Loading