diff --git a/CHANGELOG.md b/CHANGELOG.md index f3e4d0465..a6d598afd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Features +- [#83](https://github.com/alleslabs/celatone-frontend/pull/83) Add invalid code state - [#73](https://github.com/alleslabs/celatone-frontend/pull/73) Wireup migration table - [#77](https://github.com/alleslabs/celatone-frontend/pull/77) Wireup code info section in code details page - [#80](https://github.com/alleslabs/celatone-frontend/pull/80) Fix the misalignment of state in the PastTx page diff --git a/src/lib/components/state/InvalidState.tsx b/src/lib/components/state/InvalidState.tsx new file mode 100644 index 000000000..e2ef8ebd7 --- /dev/null +++ b/src/lib/components/state/InvalidState.tsx @@ -0,0 +1,27 @@ +import { Flex, Heading, Icon, Text } from "@chakra-ui/react"; +import { MdSearchOff } from "react-icons/md"; + +interface InvalidStateProps { + title: string; +} + +export const InvalidState = ({ title }: InvalidStateProps) => ( + + + + {title} + + + Please double-check your input and make sure you have selected the correct + network. + + +); diff --git a/src/lib/model/code.ts b/src/lib/model/code.ts index 407a7457a..71bb04602 100644 --- a/src/lib/model/code.ts +++ b/src/lib/model/code.ts @@ -7,9 +7,9 @@ import { useContractListCountByCodeId, } from "lib/services/codeService"; import type { ContractInfo } from "lib/stores/contract"; -import type { CodeDetails, ContractInstances, Option } from "lib/types"; +import type { CodeData, ContractInstances, Option } from "lib/types"; -export const useCodeData = (codeId: number): Option => { +export const useCodeData = (codeId: number): Option => { const { currentChainRecord } = useWallet(); const { data: codeInfo } = useCodeInfoByCodeId(codeId); if (!currentChainRecord || !codeInfo) return undefined; @@ -17,7 +17,7 @@ export const useCodeData = (codeId: number): Option => { return { chainId: currentChainRecord.chain.chain_id, ...codeInfo, - } as CodeDetails; + } as CodeData; }; export const useCodeContractInstances = ( diff --git a/src/lib/pages/code/component/CTASection.tsx b/src/lib/pages/code-details/component/CTASection.tsx similarity index 100% rename from src/lib/pages/code/component/CTASection.tsx rename to src/lib/pages/code-details/component/CTASection.tsx diff --git a/src/lib/pages/code/component/CodeInfoSection.tsx b/src/lib/pages/code-details/component/CodeInfoSection.tsx similarity index 89% rename from src/lib/pages/code/component/CodeInfoSection.tsx rename to src/lib/pages/code-details/component/CodeInfoSection.tsx index 0b2a213e6..c963e0a9e 100644 --- a/src/lib/pages/code/component/CodeInfoSection.tsx +++ b/src/lib/pages/code-details/component/CodeInfoSection.tsx @@ -6,16 +6,16 @@ import { ExplorerLink } from "lib/components/ExplorerLink"; import { LabelText } from "lib/components/LabelText"; import { PermissionChip } from "lib/components/PermissionChip"; import { useGetAddressType } from "lib/hooks"; -import type { CodeDetails, Option, PermissionAddresses } from "lib/types"; +import type { CodeData, Option, PermissionAddresses } from "lib/types"; import { dateFromNow, formatUTC, getAddressTypeText } from "lib/utils"; interface CodeInfoSectionProps { - codeDetails: Option; + codeData: Option; } const getMethodSpecificRender = ( - codeProposalInfo: CodeDetails["proposal"], - codeTxInfo: Pick + codeProposalInfo: CodeData["proposal"], + codeTxInfo: Pick ): { methodRender: JSX.Element; storedBlockRender: JSX.Element } => { if (codeProposalInfo) { return { @@ -120,7 +120,7 @@ const ViewAddresses = ({ ); }; -const CodeDetailsRender = ({ codeDetails }: { codeDetails: CodeDetails }) => { +const CodeDetailsRender = ({ codeData }: { codeData: CodeData }) => { const getAddressType = useGetAddressType(); const { hash, @@ -130,7 +130,7 @@ const CodeDetailsRender = ({ codeDetails }: { codeDetails: CodeDetails }) => { uploader, instantiatePermission, permissionAddresses, - } = codeDetails; + } = codeData; const { methodRender, storedBlockRender } = getMethodSpecificRender( proposal, { @@ -142,7 +142,7 @@ const CodeDetailsRender = ({ codeDetails }: { codeDetails: CodeDetails }) => { const uploaderType = getAddressType(uploader); return ( - {codeDetails.chainId ?? "unknown"} + {codeData.chainId ?? "unknown"} @@ -170,14 +170,14 @@ const CodeDetailsRender = ({ codeDetails }: { codeDetails: CodeDetails }) => { ); }; -export const CodeInfoSection = ({ codeDetails }: CodeInfoSectionProps) => { +export const CodeInfoSection = ({ codeData }: CodeInfoSectionProps) => { return ( Code Information - {codeDetails ? ( - + {codeData ? ( + ) : ( Error fetching data diff --git a/src/lib/pages/code/index.tsx b/src/lib/pages/code-details/index.tsx similarity index 70% rename from src/lib/pages/code/index.tsx rename to src/lib/pages/code-details/index.tsx index 733fbd0c0..ac15b2ac2 100644 --- a/src/lib/pages/code/index.tsx +++ b/src/lib/pages/code-details/index.tsx @@ -5,33 +5,28 @@ import { useRouter } from "next/router"; import { BackButton } from "lib/components/button/BackButton"; import { ExplorerLink } from "lib/components/ExplorerLink"; import PageContainer from "lib/components/PageContainer"; +import { InvalidState } from "lib/components/state/InvalidState"; import { useCodeStore } from "lib/hooks"; import { useCodeData } from "lib/model/code"; import { InstantiatePermission } from "lib/types"; -import { getFirstQueryParam } from "lib/utils"; +import { getFirstQueryParam, isCodeId } from "lib/utils"; import { CodeInfoSection } from "./component/CodeInfoSection"; import { CTASection } from "./component/CTASection"; -const CodeDetails = observer(() => { - const router = useRouter(); - /** - * @todos Handle incorrect codeIdParam and render not found or error page. - */ - const codeIdParam = getFirstQueryParam(router.query.codeId); - const codeId = Number(codeIdParam); +interface CodeDetailsBodyProps { + codeId: number; +} + +const InvalidCode = () => ; +const CodeDetailsBody = ({ codeId }: CodeDetailsBodyProps) => { const { getCodeLocalInfo } = useCodeStore(); const localCodeInfo = getCodeLocalInfo(codeId); - const codeDetails = useCodeData(codeId); - /** - * @todos Wireup page with data hook and component functionality/logic - */ + const codeData = useCodeData(codeId); + if (!codeData) return ; return ( - - - {/* Code ID and CTAs Section */} - {/* TODO: Wireup CTAs logic and render ExplorerLink for Code ID */} + <> @@ -44,19 +39,18 @@ const CodeDetails = observer(() => { - {/* TODO: check default uploader case */} - + {/* TODO: Wireup badge count, Create table component and wireup with real data */} @@ -69,6 +63,22 @@ const CodeDetails = observer(() => { Table Goes Hereeee + + ); +}; + +const CodeDetails = observer(() => { + const router = useRouter(); + const codeIdParam = getFirstQueryParam(router.query.codeId); + + return ( + + + {!isCodeId(codeIdParam) ? ( + + ) : ( + + )} ); }); diff --git a/src/lib/pages/contract-details/index.tsx b/src/lib/pages/contract-details/index.tsx index ae82195ab..fbebfc877 100644 --- a/src/lib/pages/contract-details/index.tsx +++ b/src/lib/pages/contract-details/index.tsx @@ -5,16 +5,14 @@ import { Tabs, TabPanels, TabPanel, - Icon, - Text, } from "@chakra-ui/react"; import { observer } from "mobx-react-lite"; import { useRouter } from "next/router"; -import { MdSearchOff } from "react-icons/md"; import { BackButton } from "lib/components/button/BackButton"; import { CustomTab } from "lib/components/CustomTab"; import PageContainer from "lib/components/PageContainer"; +import { InvalidState } from "lib/components/state/InvalidState"; import { useValidateAddress } from "lib/hooks"; import { useContractData, @@ -36,26 +34,7 @@ interface ContractDetailsBodyProps { contractAddress: ContractAddr; } -const InvalidContract = () => ( - - - - Contract does not exist - - - Please double-check your spelling and make sure you have selected the - correct network. - - -); +const InvalidContract = () => ; const ContractDetailsBody = ({ contractAddress }: ContractDetailsBodyProps) => { const contractData = useContractData(contractAddress); diff --git a/src/lib/services/codeService.ts b/src/lib/services/codeService.ts index dbda05be0..03d232d9a 100644 --- a/src/lib/services/codeService.ts +++ b/src/lib/services/codeService.ts @@ -13,7 +13,7 @@ import { import type { ContractInfo } from "lib/stores/contract"; import type { CodeInfo, - CodeDetails, + CodeData, ContractAddr, Option, InstantiatePermission, @@ -81,7 +81,7 @@ export const useCodeListByIDsQuery = (ids: Option) => { export const useCodeInfoByCodeId = ( codeId: Option -): UseQueryResult>> => { +): UseQueryResult>> => { const queryFn = useCallback(async () => { if (!codeId) return undefined; diff --git a/src/lib/types/code.ts b/src/lib/types/code.ts index 3476e49a6..4a69d7de1 100644 --- a/src/lib/types/code.ts +++ b/src/lib/types/code.ts @@ -26,7 +26,7 @@ interface CodeProposal { created: Date; } -export interface CodeDetails { +export interface CodeData { chainId: Option; codeId: number; uploader: ContractAddr | HumanAddr; diff --git a/src/pages/code/[codeId].ts b/src/pages/code/[codeId].ts index dfdb07870..5442c3a10 100644 --- a/src/pages/code/[codeId].ts +++ b/src/pages/code/[codeId].ts @@ -1,3 +1,3 @@ -import CodeDetails from "lib/pages/code"; +import CodeDetails from "lib/pages/code-details"; export default CodeDetails;