diff --git a/idea/vara-eth/frontend/src/components/ui/chain-entity/chain-entity.tsx b/idea/vara-eth/frontend/src/components/ui/chain-entity/chain-entity.tsx index 8e1cefbb38..9f1446a33b 100644 --- a/idea/vara-eth/frontend/src/components/ui/chain-entity/chain-entity.tsx +++ b/idea/vara-eth/frontend/src/components/ui/chain-entity/chain-entity.tsx @@ -3,6 +3,7 @@ import { PropsWithChildren } from 'react'; import { useNavigate } from 'react-router-dom'; import ArrowLeftSVG from '@/assets/icons/arrow-square-left.svg?react'; +import { formatDate } from '@/shared/utils'; import { Button } from '../button'; import { ExplorerLink } from '../explorer-link'; @@ -46,19 +47,27 @@ const Key = ({ children }: PropsWithChildren) => { return

{children}

; }; +type DateProps = { + value: string; +}; + +const Date = ({ value }: DateProps) => { + return
{formatDate(value)}
; +}; + type BlockProps = { - number: string; + value: string; date: string; }; -const Block = ({ number, date }: BlockProps) => { +const BlockNumber = ({ value, date }: BlockProps) => { return (
- #{number} + #{value}
-
{new Date(date).toLocaleString()}
+
); }; @@ -86,7 +95,8 @@ const ChainEntity = { Title, Data, Key, - Block, + Date, + BlockNumber, NotFound, }; diff --git a/idea/vara-eth/frontend/src/components/ui/index.ts b/idea/vara-eth/frontend/src/components/ui/index.ts index 7867c9e0c7..87ef74fcba 100644 --- a/idea/vara-eth/frontend/src/components/ui/index.ts +++ b/idea/vara-eth/frontend/src/components/ui/index.ts @@ -6,7 +6,6 @@ export { ExpandableItem } from './expandable-item'; export { HashLink } from './hash-link'; export { UploadIdlButton } from './upload-idl-button'; export { Loader } from './loader'; -export { NotFound } from './not-found'; export { Pagination } from './pagination'; export { SyntaxHighlighter } from './syntax-highlighter'; export { Table } from './table'; diff --git a/idea/vara-eth/frontend/src/components/ui/not-found/index.ts b/idea/vara-eth/frontend/src/components/ui/not-found/index.ts deleted file mode 100644 index 4324bddd0a..0000000000 --- a/idea/vara-eth/frontend/src/components/ui/not-found/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { NotFound } from './not-found'; diff --git a/idea/vara-eth/frontend/src/components/ui/not-found/not-found.module.scss b/idea/vara-eth/frontend/src/components/ui/not-found/not-found.module.scss deleted file mode 100644 index 569e8578a5..0000000000 --- a/idea/vara-eth/frontend/src/components/ui/not-found/not-found.module.scss +++ /dev/null @@ -1,22 +0,0 @@ -.notFound { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - min-height: 300px; - text-align: center; - gap: 16px; - - h2 { - font-size: 20px; - font-weight: 500; - margin: 0; - color: rgba(255, 255, 255, 1); - } - - p { - font-size: 16px; - margin: 0; - color: rgba(255, 255, 255, 0.7); - } -} diff --git a/idea/vara-eth/frontend/src/components/ui/not-found/not-found.tsx b/idea/vara-eth/frontend/src/components/ui/not-found/not-found.tsx deleted file mode 100644 index d732091169..0000000000 --- a/idea/vara-eth/frontend/src/components/ui/not-found/not-found.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { HashLink } from '../hash-link'; - -import styles from './not-found.module.scss'; - -type Props = { - entity: string; - id?: string; -}; - -const NotFound = ({ entity, id }: Props) => { - const title = `${entity} not found`; - - return ( -
-

{title}

- {id && ( -

- The {entity} with ID does not exist. -

- )} -
- ); -}; - -export { NotFound }; diff --git a/idea/vara-eth/frontend/src/features/messages/components/message-data/message-data.tsx b/idea/vara-eth/frontend/src/features/messages/components/message-data/message-data.tsx index 8d2dbbcbd8..a2fa9790e0 100644 --- a/idea/vara-eth/frontend/src/features/messages/components/message-data/message-data.tsx +++ b/idea/vara-eth/frontend/src/features/messages/components/message-data/message-data.tsx @@ -27,7 +27,7 @@ const MessageRequestData = (props: MessageRequest) => { Block Number - + ); }; @@ -60,7 +60,7 @@ const MessageSentData = ({ sourceProgramId, destination, value, isCall, stateTra )} Created At -
{new Date(createdAt).toLocaleString()}
+ ); }; @@ -86,7 +86,7 @@ const ReplyRequestData = ({ sourceAddress, programId, value, txHash, blockNumber Block Number - + ); }; @@ -127,7 +127,7 @@ const ReplySentData = (props: ReplySent) => { )} Created At -
{new Date(createdAt).toLocaleString()}
+ ); }; diff --git a/idea/vara-eth/frontend/src/features/programs/lib/queries.ts b/idea/vara-eth/frontend/src/features/programs/lib/queries.ts index df244c7d34..744a0520e9 100644 --- a/idea/vara-eth/frontend/src/features/programs/lib/queries.ts +++ b/idea/vara-eth/frontend/src/features/programs/lib/queries.ts @@ -1,4 +1,5 @@ import { useQuery } from '@tanstack/react-query'; +import { HexString } from '@vara-eth/api'; import { type Code } from '@/features/codes/lib/requests'; import { EXPLORER_URL } from '@/shared/config'; @@ -6,12 +7,12 @@ import { PaginatedResponse } from '@/shared/types'; import { fetchWithGuard } from '@/shared/utils'; export type Program = { - id: string; + id: HexString; blockNumber: string; - code: Code; - createdAt: number; - txHash: string; - abiInterfaceAddress: string | null; + createdAt: string; + txHash: HexString; + abiInterfaceAddress?: string | null; + code?: Code; }; export type ProgramsResponse = PaginatedResponse; diff --git a/idea/vara-eth/frontend/src/pages/code/code.module.scss b/idea/vara-eth/frontend/src/pages/code/code.module.scss index 150a707aee..d7b04adad8 100644 --- a/idea/vara-eth/frontend/src/pages/code/code.module.scss +++ b/idea/vara-eth/frontend/src/pages/code/code.module.scss @@ -7,28 +7,6 @@ border-radius: 0 0 4px 4px; } -.header { - display: flex; - align-items: center; - gap: 8px; - justify-content: space-between; - - .leftSide { - display: flex; - align-items: center; - gap: 8px; - font-size: 15px; - } - - .link { - display: flex; - } - - .arrowLeft { - margin-right: 4px; - } -} - .card { padding: 24px 24px 12px 24px; @@ -37,13 +15,6 @@ } } -.properties { - margin-top: 24px; - display: grid; - grid-template-columns: 145px 1fr; - gap: 20px 24px; -} - .programs { color: rgba(168, 245, 147, 1); } diff --git a/idea/vara-eth/frontend/src/pages/code/code.tsx b/idea/vara-eth/frontend/src/pages/code/code.tsx index bd98ce7cc0..1ed244c44f 100644 --- a/idea/vara-eth/frontend/src/pages/code/code.tsx +++ b/idea/vara-eth/frontend/src/pages/code/code.tsx @@ -1,12 +1,10 @@ import { HexString } from '@vara-eth/api'; -import { useNavigate, useParams } from 'react-router-dom'; +import { Link, useParams } from 'react-router-dom'; -import ArrowLeftSVG from '@/assets/icons/arrow-square-left.svg?react'; -import { Badge, Button, HashLink, UploadIdlButton, NotFound, SyntaxHighlighter } from '@/components'; +import { Badge, UploadIdlButton, SyntaxHighlighter, ChainEntity } from '@/components'; import { useGetCodeByIdQuery } from '@/features/codes/lib/queries'; import { routes } from '@/shared/config'; import { useIdlStorage } from '@/shared/hooks'; -import { formatDate } from '@/shared/utils'; import styles from './code.module.scss'; @@ -15,67 +13,53 @@ type Params = { }; const Code = () => { - const navigate = useNavigate(); - const params = useParams(); - const codeId = params?.codeId; + const { codeId } = useParams() as Params; - const { data: code, isLoading, error } = useGetCodeByIdQuery(codeId); + const { data: code, isLoading } = useGetCodeByIdQuery(codeId); const { idl, saveIdl } = useIdlStorage(codeId); if (isLoading) { return (
-
-
Loading...
-
+
Loading...
); } - if (error || !code || !codeId) { - return ; + if (!code) { + return ; } - const createdDateTime = formatDate(code.createdAt); - return (
-
-
- - -
- {/* TODO: add after code verifier is implemented */} - {/* {isVerify && ( - - - - )} */} -
- -
-
SERVICES
+ + + + + + + Services +
SERVICE 1 + SERVICE 2
-
PROGRAMS
- {/* TODO: add filtered programs page */} - + Programs + + 3 programs - + -
CREATED AT
-
{createdDateTime}
-
+ Created at + +
diff --git a/idea/vara-eth/frontend/src/pages/program/program.module.scss b/idea/vara-eth/frontend/src/pages/program/program.module.scss index 68778301ca..65695b33f7 100644 --- a/idea/vara-eth/frontend/src/pages/program/program.module.scss +++ b/idea/vara-eth/frontend/src/pages/program/program.module.scss @@ -7,28 +7,6 @@ border-radius: 0 0 4px 4px; } -.header { - display: flex; - align-items: center; - gap: 8px; - justify-content: space-between; - - .leftSide { - display: flex; - align-items: center; - gap: 8px; - font-size: 16px; - } - - .link { - display: flex; - } - - .arrowLeft { - margin-right: 4px; - } -} - .card { padding: 24px; @@ -37,30 +15,16 @@ } } -.name { - padding-left: 32px; - color: #fff; -} - -.properties { - margin-top: 24px; - display: grid; - grid-template-columns: 136px 1fr; - gap: 20px 24px; +.status { + margin-left: auto; } -.property { +.executableBalance { display: flex; align-items: center; gap: 8px; } -.blockHash { - display: flex; - flex-direction: column; - gap: 4px; -} - .emptyState { display: flex; flex-direction: column; diff --git a/idea/vara-eth/frontend/src/pages/program/program.tsx b/idea/vara-eth/frontend/src/pages/program/program.tsx index f5763821be..60e8051e44 100644 --- a/idea/vara-eth/frontend/src/pages/program/program.tsx +++ b/idea/vara-eth/frontend/src/pages/program/program.tsx @@ -1,16 +1,14 @@ import { HexString } from '@vara-eth/api'; -import { generatePath, useNavigate, useParams } from 'react-router-dom'; +import { generatePath, useParams } from 'react-router-dom'; +import { formatEther, formatUnits } from 'viem'; import { useApproveWrappedVara, useWrappedVaraBalance } from '@/app/api'; -import { useVaraEthApi } from '@/app/providers'; -import ArrowLeftSVG from '@/assets/icons/arrow-square-left.svg?react'; -import EtherscanSvg from '@/assets/icons/etherscan.svg?react'; -import { Badge, Balance, Button, HashLink, NotFound, Tooltip, UploadIdlButton } from '@/components'; +import { Badge, Balance, Button, ChainEntity, HashLink, UploadIdlButton } from '@/components'; import { ServiceList, useExecutableBalanceTopUp } from '@/features/programs'; import { useReadContractState, useGetProgramByIdQuery } from '@/features/programs/lib'; import { routes } from '@/shared/config'; import { useIdlStorage } from '@/shared/hooks'; -import { formatBalance, formatDate, formatNumber } from '@/shared/utils'; +import { isUndefined } from '@/shared/utils'; import styles from './program.module.scss'; @@ -19,27 +17,20 @@ type Params = { }; const Program = () => { - const navigate = useNavigate(); - const params = useParams(); - const programId = params.programId!; + const { programId } = useParams() as Params; + const approveWrappedVara = useApproveWrappedVara(programId); const executableBalanceTopUp = useExecutableBalanceTopUp(programId); - const { isApiReady } = useVaraEthApi(); - const { data: program, isLoading, error } = useGetProgramByIdQuery(programId); - const { data: programState, refetch, isLoading: isProgramStateLoading } = useReadContractState(programId); + const { data: program, isLoading } = useGetProgramByIdQuery(programId); + const codeId = program?.code?.id; // TODO: program.codeId property should be present? - const { decimals } = useWrappedVaraBalance(programId); + const { data: programState, refetch, isLoading: isProgramStateLoading } = useReadContractState(programId); const isActive = programState && 'Active' in programState.program; const isInitialized = isActive && programState.program.Active.initialized; - const programName = ''; // TODO: get program name when it's implemented - const codeId = program?.code?.id; - const blockHash = program?.txHash || ''; - const formattedCreatedAt = program?.createdAt ? formatDate(program.createdAt) : ''; - const { idl, saveIdl } = useIdlStorage(codeId); - const executableBalance = - programState && decimals ? formatBalance(BigInt(programState.executableBalance), decimals) : null; + const { decimals, isPending: isDecimalsPending } = useWrappedVaraBalance(programId); + const { idl, saveIdl } = useIdlStorage(codeId); const onTopUp = async () => { const topUpValue = BigInt(10 * 1e12); @@ -49,70 +40,47 @@ const Program = () => { await refetch(); }; - if (isLoading || isProgramStateLoading || !isApiReady) { + if (isLoading || isProgramStateLoading || isDecimalsPending) { return (
-
-
Loading...
-
+
Loading...
); } - if (error || !programState) { - return ; + if (!program || !programState || !codeId || isUndefined(decimals)) { + return ; } - const serviceListContent = () => { - if (idl) return ; - if (!codeId) return null; - return ( -
-

No IDL uploaded. Please upload an IDL file to initialize and interact with the program.

- -
- ); - }; - return (
-
-
- - - - {/* TODO: support mainnet */} - - - - -
- {isActive && (isInitialized ? Active : Uninitialized)} -
+ + + + + {isActive && ( + + {isInitialized ? 'Active' : 'Uninitialized'} + + )} + - {programName &&
{programName}
} + + Code ID + + + Transaction Hash + + + Program Balance + + + Executable Balance + +
+ -
- {codeId && ( - <> -
CODE ID
- - - )} -
PROGRAM BALANCE
-
- -
-
EXECUTABLE BALANCE
-
-
- {blockHash && ( - <> -
BLOCK HASH
-
- - {formattedCreatedAt} -
- - )} -
+ + Block Number + +
-
{serviceListContent()}
+
+ {idl ? ( + + ) : ( +
+

No IDL uploaded. Please upload an IDL file to initialize and interact with the program.

+ +
+ )} +
); }; diff --git a/idea/vara-eth/frontend/src/pages/user/user.module.scss b/idea/vara-eth/frontend/src/pages/user/user.module.scss index 4ada3ea70a..0c78a32fb9 100644 --- a/idea/vara-eth/frontend/src/pages/user/user.module.scss +++ b/idea/vara-eth/frontend/src/pages/user/user.module.scss @@ -7,28 +7,6 @@ border-radius: 0 0 4px 4px; } -.header { - display: flex; - align-items: center; - gap: 8px; - justify-content: space-between; - - .leftSide { - display: flex; - align-items: center; - gap: 8px; - font-size: 16px; - } - - .link { - display: flex; - } - - .arrowLeft { - margin-right: 4px; - } -} - .card { padding: 24px; @@ -37,26 +15,12 @@ } } -.name { - padding-left: 32px; - color: #fff; -} +.title { + font-size: 16px; + font-weight: 400; -.properties { - margin-top: 24px; - display: grid; - grid-template-columns: 145px 1fr; - gap: 20px 24px; -} + // TODO: remove after default heading capitalize is gone + text-transform: none; -.property { - display: flex; - align-items: center; - gap: 8px; -} - -.blockHash { - display: flex; - flex-direction: column; - gap: 4px; + color: #fff; } diff --git a/idea/vara-eth/frontend/src/pages/user/user.tsx b/idea/vara-eth/frontend/src/pages/user/user.tsx index 28c4dcf24d..04f9ba7fd7 100644 --- a/idea/vara-eth/frontend/src/pages/user/user.tsx +++ b/idea/vara-eth/frontend/src/pages/user/user.tsx @@ -1,11 +1,10 @@ import { HexString } from '@vara-eth/api'; import { useParams } from 'react-router-dom'; +import { formatEther, formatUnits, isAddress } from 'viem'; import { useBalance } from 'wagmi'; import { useWrappedVaraBalance } from '@/app/api'; -import EtherscanSvg from '@/assets/icons/etherscan.svg?react'; -import { Balance, HashLink, Tooltip } from '@/components'; -import { formatBalance } from '@/shared/utils'; +import { Balance, ChainEntity } from '@/components'; import styles from './user.module.scss'; @@ -15,39 +14,29 @@ type Params = { export const User = () => { const { userId } = useParams() as Params; - - const address = userId.startsWith('0x') ? userId : undefined; + const address = isAddress(userId) ? userId : undefined; const { data: ethBalance } = useBalance({ address }); const { value, decimals } = useWrappedVaraBalance(address); - const wvara = value !== undefined && decimals ? formatBalance(value, decimals) : null; - const eth = ethBalance ? formatBalance(ethBalance.value, ethBalance.decimals) : null; + const wvara = value !== undefined && decimals ? formatUnits(value, decimals) : null; + const eth = ethBalance ? formatEther(ethBalance.value) : null; return (
-
-
- - - {/* TODO: support mainnet */} - - - - -
-
+ +

Address

+ +
-
-
BALANCE
- {wvara && } - {eth && } -
+ + Balance + +
+ {wvara && } | {eth && } +
+
); diff --git a/idea/vara-eth/frontend/src/shared/utils/index.ts b/idea/vara-eth/frontend/src/shared/utils/index.ts index 84c0c2631a..1bf62ed6e8 100644 --- a/idea/vara-eth/frontend/src/shared/utils/index.ts +++ b/idea/vara-eth/frontend/src/shared/utils/index.ts @@ -52,13 +52,7 @@ const formatBalance = (value: bigint, decimals: number) => { return polkadotFormatBalance(value, { decimals, forceUnit: '-', withSi: false, withUnit: false }); }; -const formatDate = (rawDate: string | number) => { - const date = new Date(rawDate); - const time = date.toLocaleTimeString('en-GB'); - const formatedDate = date.toLocaleDateString('en-US').replace(/\//g, '-'); - - return `${formatedDate} ${time}`; -}; +const formatDate = (value: string | number) => new Date(value).toLocaleString(); const getPreformattedText = (data: unknown) => JSON.stringify(data, null, 4);