diff --git a/examples/chain-template/components/contract/EmptyState.tsx b/examples/chain-template/components/contract/EmptyState.tsx new file mode 100644 index 00000000..eab98f75 --- /dev/null +++ b/examples/chain-template/components/contract/EmptyState.tsx @@ -0,0 +1,17 @@ +import Image from 'next/image'; +import { Box, Text } from '@interchain-ui/react'; + +export const EmptyState = ({ text }: { text: string }) => ( + + empty + + {text} + + +); diff --git a/examples/chain-template/components/contract/ExecuteTab.tsx b/examples/chain-template/components/contract/ExecuteTab.tsx new file mode 100644 index 00000000..3b7082a4 --- /dev/null +++ b/examples/chain-template/components/contract/ExecuteTab.tsx @@ -0,0 +1,19 @@ +import { Box, Text } from '@interchain-ui/react'; + +type ExecuteTabProps = { + show: boolean; + initialAddress: string; + clearInitAddress: () => void; +}; + +export const ExecuteTab = ({ + show, + initialAddress, + clearInitAddress, +}: ExecuteTabProps) => { + return ( + + Execute Contract + + ); +}; diff --git a/examples/chain-template/components/contract/MyContractsTab.tsx b/examples/chain-template/components/contract/MyContractsTab.tsx new file mode 100644 index 00000000..f8707337 --- /dev/null +++ b/examples/chain-template/components/contract/MyContractsTab.tsx @@ -0,0 +1,129 @@ +import { useState } from 'react'; +import { useChain } from '@cosmos-kit/react'; +import { Box, Icon, Spinner, Text } from '@interchain-ui/react'; + +import { useCopyToClipboard, useMyContracts } from '@/hooks'; +import { Button, Table } from '../common'; +import { shortenAddress } from '@/utils'; +import { TabLabel } from '@/pages/contract'; +import { EmptyState } from './EmptyState'; +import { useChainStore } from '@/contexts'; + +type MyContractsTabProps = { + show: boolean; + switchTab: (initialAddress: string, tabId: number) => void; +}; + +export const MyContractsTab = ({ show, switchTab }: MyContractsTabProps) => { + const { selectedChain } = useChainStore(); + const { address } = useChain(selectedChain); + const { data: myContracts = [], isLoading } = useMyContracts(); + + return ( + + + My contracts + + + {!address ? ( + + ) : isLoading ? ( + + ) : myContracts.length === 0 ? ( + + ) : ( + + + + + + Contract Address + + Contract Name + Code ID + + + + + {myContracts.map(({ address, contractInfo }) => ( + + + + + {contractInfo?.label} + + {Number(contractInfo?.codeId)} + + + + + + + + + ))} + +
+
+ )} +
+
+ ); +}; + +const CopyText = ({ + copyValue, + displayValue, +}: { + displayValue: string; + copyValue: string; +}) => { + const [isHover, setIsHover] = useState(false); + const { copyToClipboard, isCopied } = useCopyToClipboard(); + + return ( + setIsHover(true), + onMouseLeave: () => setIsHover(false), + onClick: () => copyToClipboard(copyValue), + }} + > + + {displayValue} + + {isHover && ( + + + + )} + + ); +}; diff --git a/examples/chain-template/components/contract/QueryTab.tsx b/examples/chain-template/components/contract/QueryTab.tsx new file mode 100644 index 00000000..745c1f21 --- /dev/null +++ b/examples/chain-template/components/contract/QueryTab.tsx @@ -0,0 +1,19 @@ +import { Box, Text } from '@interchain-ui/react'; + +type QueryTabProps = { + show: boolean; + initialAddress: string; + clearInitAddress: () => void; +}; + +export const QueryTab = ({ + show, + initialAddress, + clearInitAddress, +}: QueryTabProps) => { + return ( + + Query Contract + + ); +}; diff --git a/examples/chain-template/components/contract/index.ts b/examples/chain-template/components/contract/index.ts new file mode 100644 index 00000000..1848e3e4 --- /dev/null +++ b/examples/chain-template/components/contract/index.ts @@ -0,0 +1,3 @@ +export * from './QueryTab'; +export * from './ExecuteTab'; +export * from './MyContractsTab'; diff --git a/examples/chain-template/components/index.ts b/examples/chain-template/components/index.ts index faa582f0..9b9594a6 100644 --- a/examples/chain-template/components/index.ts +++ b/examples/chain-template/components/index.ts @@ -2,3 +2,4 @@ export * from './common'; export * from './staking'; export * from './voting'; export * from './asset-list'; +export * from './contract'; diff --git a/examples/chain-template/hooks/contract/useStoreCodeTx.tsx b/examples/chain-template/hooks/contract/useStoreCodeTx.tsx index 48e32af1..6aa79303 100644 --- a/examples/chain-template/hooks/contract/useStoreCodeTx.tsx +++ b/examples/chain-template/hooks/contract/useStoreCodeTx.tsx @@ -40,7 +40,7 @@ export const useStoreCodeTx = (chainName: string) => { }); const wasmCode = await wasmFile.arrayBuffer(); - const wasmByteCode = await gzip(new Uint8Array(wasmCode)); + const wasmByteCode = new Uint8Array(await gzip(new Uint8Array(wasmCode))); const message = storeCode({ sender: address, diff --git a/examples/chain-template/pages/contract.tsx b/examples/chain-template/pages/contract.tsx index 005f8697..07e75e91 100644 --- a/examples/chain-template/pages/contract.tsx +++ b/examples/chain-template/pages/contract.tsx @@ -1,5 +1,65 @@ -import { Box } from '@interchain-ui/react'; +import { useEffect, useState } from 'react'; +import { Box, Tabs } from '@interchain-ui/react'; + +import { ExecuteTab, MyContractsTab, QueryTab } from '@/components'; +import { splitCamelCase } from '@/utils'; +import styles from '@/styles/comp.module.css'; + +export enum TabLabel { + MyContracts, + Query, + Execute, +} export default function Contract() { - return Contract; + const [activeTab, setActiveTab] = useState(TabLabel.MyContracts); + const [initQueryAddress, setInitQueryAddress] = useState(''); + const [initExecuteAddress, setInitExecuteAddress] = useState(''); + + useEffect(() => { + if (activeTab !== TabLabel.Query) setInitQueryAddress(''); + if (activeTab !== TabLabel.Execute) setInitExecuteAddress(''); + }, [activeTab]); + + const switchTabWithAddress = (address: string, tabId: TabLabel) => { + setActiveTab(tabId); + if (tabId === TabLabel.Query) setInitQueryAddress(address); + if (tabId === TabLabel.Execute) setInitExecuteAddress(address); + }; + + return ( + <> + typeof v === 'string') + .map((label) => ({ + label: splitCamelCase(label as string), + content: undefined, + }))} + activeTab={activeTab} + onActiveTabChange={(tabId) => setActiveTab(tabId)} + className={styles.tabs} + /> + + + { + if (initQueryAddress) setInitQueryAddress(''); + }} + /> + { + if (initExecuteAddress) setInitExecuteAddress(''); + }} + /> + + + ); }