From b731a2e5c498e786a47ead3aa43baf4b8a205b2e Mon Sep 17 00:00:00 2001 From: Ruben Gutierrez Date: Fri, 18 Nov 2022 10:22:19 -0400 Subject: [PATCH 01/13] i18n english --- components/Header/Header.tsx | 37 ++++++++ components/InfoCard/InfoCard.tsx | 10 ++- components/SearchBar/SearchBar.tsx | 12 +-- hooks/useFormatIntl.tsx | 13 +++ i18n/en.ts | 90 +++++++++++++++++++ i18n/es.ts | 74 ++++++++++++++++ next.config.js | 6 ++ package.json | 5 +- pages/_app.tsx | 70 +++++++-------- pages/block/details/[hash].tsx | 26 +++--- pages/blocks.tsx | 20 +++-- pages/contracts.tsx | 18 ++-- pages/contracts/contract/[address].tsx | 26 +++--- pages/transaction/details/[hash].tsx | 64 +++++++------- pages/transactions.tsx | 20 +++-- pnpm-lock.yaml | 114 ++++++++++++++++++++++++- 16 files changed, 472 insertions(+), 133 deletions(-) create mode 100644 components/Header/Header.tsx create mode 100644 hooks/useFormatIntl.tsx create mode 100644 i18n/en.ts create mode 100644 i18n/es.ts diff --git a/components/Header/Header.tsx b/components/Header/Header.tsx new file mode 100644 index 0000000..51f5110 --- /dev/null +++ b/components/Header/Header.tsx @@ -0,0 +1,37 @@ +import { useRouter } from 'next/router' +import { useEffect, useState } from 'react' +import { Col, Row } from 'react-bootstrap' +import { useFormatIntl } from '../../hooks/useFormatIntl' +import { getTitle } from '../../utils/pagetitile' +import InfoCard from '../InfoCard/InfoCard' +import Searchbar from '../SearchBar/SearchBar' + +export const Header = () => { + const { format } = useFormatIntl() + const [title, setTitle] = useState('') + const router = useRouter() + useEffect(() => { + const value: string = getTitle(router.pathname) + setTitle(value) + }, [router]) + + return ( + <> +
+ +
+ + + +

{title.toLowerCase() ? format(title.toLowerCase()) : ''}

+ + +
+ +
+ +
+ + + ) +} diff --git a/components/InfoCard/InfoCard.tsx b/components/InfoCard/InfoCard.tsx index 331a967..50c3899 100644 --- a/components/InfoCard/InfoCard.tsx +++ b/components/InfoCard/InfoCard.tsx @@ -1,15 +1,16 @@ import Binance, { AvgPriceResult } from 'binance-api-node' import { get } from 'lodash' import Image from 'next/future/image' -import * as React from 'react' -import { useState } from 'react' +import { useState, useEffect } from 'react' import time from '../../assets/img/bxs_time.svg' import coin from '../../assets/img/ph_coin-vertical-fill.svg' import { useGetLastBlockQuery, GetLastBlockQuery, useVersionQuery, VersionQuery } from '../../generated' import { getTimeAgo } from '../../lib/utils' import withApollo from '../../lib/withApollo' +import { useFormatIntl } from '../../hooks/useFormatIntl' function InfoCard() { + const { format } = useFormatIntl() const [price, setPrice] = useState(0) const { data } = useGetLastBlockQuery({ variables: { skip: 0, take: 1 } }) const blocks = get(data, 'getBlocks', []) as GetLastBlockQuery['getBlocks'] @@ -17,7 +18,7 @@ function InfoCard() { const version = get(versionData, 'version', []) as VersionQuery['version'] const token = 'DOT' - React.useEffect(() => { + useEffect(() => { const client = Binance() client .avgPrice({ symbol: `${token}USDT` }) @@ -36,7 +37,8 @@ function InfoCard() { Icon {token + `: $` + price}
- Icon Latest Block: {blocks[0]?.number} ({getTimeAgo(blocks[0]?.timestamp)}) + Icon {format('lastest_block')}: {blocks[0]?.number} ( + {getTimeAgo(blocks[0]?.timestamp)})
SDK: {version}
diff --git a/components/SearchBar/SearchBar.tsx b/components/SearchBar/SearchBar.tsx index cfe3627..f71ab00 100644 --- a/components/SearchBar/SearchBar.tsx +++ b/components/SearchBar/SearchBar.tsx @@ -3,8 +3,10 @@ import Image from 'next/future/image' import React, { useState } from 'react' import { Row, Col } from 'react-bootstrap' import icon from '../../assets/img/search-icon.svg' +import { useFormatIntl } from '../../hooks/useFormatIntl' function Searchbar() { + const { format } = useFormatIntl() const [selectedType, setSelectedType] = useState('type') const [search, setSearch] = useState('') const router = useRouter() @@ -47,16 +49,16 @@ function Searchbar() { value={selectedType} onChange={change} > - - - - + + + + setSearch(e.target.value)} diff --git a/hooks/useFormatIntl.tsx b/hooks/useFormatIntl.tsx new file mode 100644 index 0000000..88cc6ea --- /dev/null +++ b/hooks/useFormatIntl.tsx @@ -0,0 +1,13 @@ +import { useIntl } from "react-intl"; + +export const useFormatIntl = () => { + const intl = useIntl(); + + const format = (id: string) => { + return intl.formatMessage({ id }); + }; + + return { + format, + }; +}; diff --git a/i18n/en.ts b/i18n/en.ts new file mode 100644 index 0000000..198726f --- /dev/null +++ b/i18n/en.ts @@ -0,0 +1,90 @@ +export const en = { + blocks: 'Blocks', + transactions: 'Transactions', + contracts: 'Contracts', + search_by: 'Search by...', + transaction_hash: 'Transaction Hash', + block_hash: 'Block Hash', + contract_address: 'Contract Address', + search_placeholder: 'Contract Address, Tx Hash, Block Hash', + lastest_block: 'Lastest Block', + + header_number: 'Number', + header_hash: 'Hash', + header_block_hash: 'Block Hash', + header_time: 'Time', + header_parent_hash: 'Parent Hash', + header_transactions: 'Transactions', + header_size: 'Size', + header_method: 'Method', + header_signer: 'Signer', + header_address: 'Address', + header_last_event: 'Last Event', + header_uploaded_metadata: 'Uploaded metadata', + header_events: 'Events', + header_timestamp: 'Timestamp', + header_parent: 'Parent', + header_tx_hash: 'Tx Hash', + header_block: 'Block', + header_section: 'Section', + header_signature: 'Signature', + header_nonce: 'Nonce', + header_encoded_length: 'Encoded Length', + header_tip: 'Tip', + header_era: 'Era', + header_args: 'Args', + header_callindex: 'callindex', + header_decimals: 'decimals', + header_ss58: 'ss58', + header_tokens: 'Tokens', + header_type: 'Type', + header_version: 'Version', + header_more: 'Version', + header_topics: 'Version', + header_data: 'Data', + + overview: 'Overview', + logs: 'Logs', + + show_more: 'Show more', + show_less: 'Show less', + + yes: 'Yes', + no: 'No', + + transaction_receipt_event_logs: 'Transaction Receipt Event Logs', + no_logs_to_show: 'No Logs to show', + + contract_abi: 'Contract ABI', + upload_abi: 'Upload ABI', + run_contract_methods: 'Run contract methods', + + contract_abi_verified: 'Contract ABI Verified', + + methos_arguments: 'Method Arguments', + show_options: 'Show Options', + hide_options: 'Hide options', + gast_limit: 'gasLimit', + storage_limit: 'Storage Limit', + value: 'value', + + contract: 'Contract', + events: 'Events', + upload_placeholder: 'Please upload the metadata of the contract in a Base64 encoded format.', + upload: 'Upload', + result: 'Result', + no_queries_found: 'No queries found. Try uploading the metadata for this contract.', + method_arguments: 'Method Arguments', + + loading: 'Loading', + successfull_upload: 'Successful Upload', + + not_found: 'Not found', + summary: 'Summary', + + send: 'send', + + no_extension_installed: 'No extension installed!', + contract_metadata_not_found: 'Contract metadata not found', + query_not_found: 'Query/Transaction method not found', +} diff --git a/i18n/es.ts b/i18n/es.ts new file mode 100644 index 0000000..4e74b2c --- /dev/null +++ b/i18n/es.ts @@ -0,0 +1,74 @@ +export const es = { + blocks: 'Blocks', + transactions: 'Transactions', + contracts: 'Contracts', + search_by: 'Search by...', + transaction_hash: 'Transaction Hash', + block_hash: 'Block Hash', + contract_address: 'Contract Address', + search_placeholder: 'Contract Address, Tx Hash, Block Hash', + lastest_block: 'Lastest Block', + + header_number: 'Number', + header_hash: 'Hash', + header_time: 'Time', + header_parent_hash: 'Parent Hash', + header_transactions: 'Transactions', + header_size: 'Size', + header_method: 'Method', + header_signer: 'Signer', + header_address: 'Address', + header_last_event: 'Last Event', + header_uploaded_metadata: 'Uploaded metadata', + header_events: 'Events', + header_timestamp: 'Timestamp', + header_parent: 'Parent', + header_tx_hash: 'Tx Hash', + header_block: 'Block', + header_section: 'Section', + header_signature: 'Signature', + header_nonce: 'Nonce', + header_encoded_length: 'Encoded Length', + header_tip: 'Tip', + header_era: 'Era', + header_args: 'Args', + header_callIndex: 'callindex', + header_decimals: 'decimals', + header_ss58: 'ss58', + header_tokens: 'Tokens', + header_type: 'Type', + header_version: 'Version', + header_more: 'Version', + header_topics: 'Version', + header_data: 'Data', + + show_more: 'Show more', + + transaction_receipt_event_logs: 'Transaction Receipt Event Logs', + no_logs_to_show: 'No Logs to show', + + contract_abi: 'Contract ABI', + upload_abi: 'Upload ABI', + run_contract_methods: 'Run contract methods', + + contract_abi_verified: 'Contract ABI Verified', + + methos_arguments: 'Method Arguments', + show_options: 'Show Options', + gast_limit: 'gasLimit', + storage_limit: 'Storage Limit', + value: 'value', + + upload_placeholder: 'Please upload the metadata of the contract in a Base64 encoded format.', + upload: 'Upload', + + no_queries_found: 'No queries found. Try uploading the metadata for this contract.', + + loading: 'Loading', + successfull_upload: 'Successfull Upload', + + not_found: 'Not found', + summary: 'Summary', + + send: 'send', +} diff --git a/next.config.js b/next.config.js index 804dacd..d6b8464 100644 --- a/next.config.js +++ b/next.config.js @@ -15,6 +15,12 @@ const nextConfig = { }, ] }, + i18n: { + // The locales you want to support in your app + locales: ['en', 'es'], + // The default locale you want to be used when visiting a non-locale prefixed path e.g. `/hello` + defaultLocale: 'en', + }, } module.exports = nextConfig diff --git a/package.json b/package.json index e15bd3f..73421c9 100644 --- a/package.json +++ b/package.json @@ -82,6 +82,7 @@ "react-bootstrap": "^2.6.0", "react-bootstrap-sidebar-menu": "^2.0.3", "react-dom": "18.2.0", + "react-intl": "^6.2.1", "react-toastify": "^9.1.1", "sass": "^1.56.1", "tls": "^0.0.1" @@ -109,7 +110,7 @@ "jest": "^29.3.1", "jest-environment-jsdom": "^29.3.1", "prettier": "^2.7.1", - "typescript": "4.9.3", - "ts-node": "^10.9.1" + "ts-node": "^10.9.1", + "typescript": "4.9.3" } } diff --git a/pages/_app.tsx b/pages/_app.tsx index e9e5f1a..975f233 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -2,62 +2,50 @@ import '../styles/globals.css' import type { AppProps } from 'next/app' import Head from 'next/head' import { useRouter } from 'next/router' -import { useEffect, useState } from 'react' -import { Row, Container, Col } from 'react-bootstrap' +import { Row, Container } from 'react-bootstrap' import { ToastContainer } from 'react-toastify' -import InfoCard from '../components/InfoCard/InfoCard' -import SearchBar from '../components/SearchBar/SearchBar' + import Sidebar from '../components/Sidebar/Sidebar' -import { getTitle } from '../utils/pagetitile' +import { IntlProvider } from 'react-intl' import 'bootstrap/dist/css/bootstrap.min.css' import '../styles/main.scss' import 'react-toastify/dist/ReactToastify.css' +import { en } from '../i18n/en' +import { es } from '../i18n/es' +import { Header } from '../components/Header/Header' + +const messages: any = { en, es } + function MyApp({ Component, pageProps }: AppProps) { - const [title, setTitle] = useState('') - const router = useRouter() - useEffect(() => { - const value: string = getTitle(router.pathname) - setTitle(value) - }, [router]) + const { locale } = useRouter() + return ( <> Ink! Explorer -
-
- -
-
-
- - -
- -
- - - -

{title}

- - -
- -
- -
- -
- -
- -
-
+ +
+
+ +
+
+
+ + +
+
+ +
+ + + +
-
+ ) } diff --git a/pages/block/details/[hash].tsx b/pages/block/details/[hash].tsx index a9e4582..feb0e86 100644 --- a/pages/block/details/[hash].tsx +++ b/pages/block/details/[hash].tsx @@ -15,10 +15,12 @@ import { useGetTransactionsByBlockQuery, } from '../../../generated' import { useToast } from '../../../hooks' +import { useFormatIntl } from '../../../hooks/useFormatIntl' import { formatTimeAgo, showShortHash } from '../../../lib/utils' import withApollo from '../../../lib/withApollo' const Block: NextPage = () => { + const { format } = useFormatIntl() const router = useRouter() const hash = router.query?.hash as string const { data, loading, error } = useGetBlockQuery({ variables: { hash } }) @@ -56,7 +58,7 @@ const Block: NextPage = () => {

- Summary + {format('summary')} {loading && }

@@ -66,11 +68,11 @@ const Block: NextPage = () => { - + - + - + - + - + @@ -102,15 +104,15 @@ const Block: NextPage = () => {
Number{format('header_number')} {block.number}
Hash{format('header_hash')} {block.hash} @@ -78,11 +80,11 @@ const Block: NextPage = () => {
Timestamp{format('header_timestamp')} {formatTimeAgo(block.timestamp)}
Parent{format('header_parent')} {block.parentHash} @@ -90,7 +92,7 @@ const Block: NextPage = () => {
Size{format('header_size')} {block.encodedLength} bytes
- - + + - - - + + + diff --git a/pages/blocks.tsx b/pages/blocks.tsx index a3e37d6..96cad85 100644 --- a/pages/blocks.tsx +++ b/pages/blocks.tsx @@ -8,10 +8,12 @@ import sortIcon from '../assets/img/sort.svg' import { Loading } from '../components/Loading/Loading' import { GetBlocksQuery, useGetBlocksQuery } from '../generated' import { useToast } from '../hooks' +import { useFormatIntl } from '../hooks/useFormatIntl' import { formatTimeAgo, showShortHash } from '../lib/utils' import withApollo from '../lib/withApollo' const Home: NextPage = () => { + const { format } = useFormatIntl() const [pagination, setPagination] = useState({ skip: 0, take: 10, orderByNumber: false, orderAsc: false }) const { data, loading, error } = useGetBlocksQuery({ variables: pagination }) const blocks = get(data, 'getBlocks', []) as GetBlocksQuery['getBlocks'] @@ -50,17 +52,17 @@ const Home: NextPage = () => { - + - + - + @@ -71,16 +73,16 @@ const Home: NextPage = () => { - + - - - + + + diff --git a/pages/contracts.tsx b/pages/contracts.tsx index d5dc2ca..c3604eb 100644 --- a/pages/contracts.tsx +++ b/pages/contracts.tsx @@ -6,10 +6,12 @@ import { Row, Col, Table, Pagination } from 'react-bootstrap' import { Loading } from '../components/Loading/Loading' import { useGetContractsQuery, GetContractsQuery } from '../generated' import { useToast } from '../hooks' +import { useFormatIntl } from '../hooks/useFormatIntl' import { formatTimeAgo } from '../lib/utils' import withApollo from '../lib/withApollo' const Contract: NextPage = () => { + const { format } = useFormatIntl() const [pagination, setPagination] = useState({ skip: 0, take: 10 }) const { data, loading, error } = useGetContractsQuery({ variables: pagination }) const contracts = get(data, 'getContracts', []) as GetContractsQuery['getContracts'] @@ -45,17 +47,17 @@ const Contract: NextPage = () => { - + - + - + @@ -64,10 +66,10 @@ const Contract: NextPage = () => {
Tx HashBlock{format('header_tx_hash')}{format('header_block')} toogleOrder()} role="button" className="d-flex align-center gap-1"> - Time + {format('header_time')} MethodSectionSigner{format('header_method')}{format('header_section')}{format('header_signer')}
toogleOrderByNumber()} role="button" className="d-flex align-center gap-1"> - Number + {format('header_number')} Hash{format('header_hash')} toogleOrderByTimestamp()} role="button" className="d-flex align-center gap-1"> - Time + {format('header_time')} Parent HashTransactionsSize{format('header_parent_hash')}{format('header_transactions')}{format('header_size')}
- - - - + + + + @@ -77,7 +79,7 @@ const Contract: NextPage = () => { {contract.address} - + ))} diff --git a/pages/contracts/contract/[address].tsx b/pages/contracts/contract/[address].tsx index 5237cda..80a4fbc 100644 --- a/pages/contracts/contract/[address].tsx +++ b/pages/contracts/contract/[address].tsx @@ -15,6 +15,7 @@ import { useGetContractQueriesQuery, GetContractQueriesQuery, useUploadMetadataM import { useLoading, useToast } from '../../../hooks' import { useSendingTx } from '../../../hooks/useSendingTx' import withApollo from '../../../lib/withApollo' +import { useFormatIntl } from '../../../hooks/useFormatIntl' const WS_PROVIDER = process.env.WS_PROVIDER || 'ws://127.0.0.1:9944' const DEFAULT_OPTIONS = { gasLimit: '' } @@ -32,6 +33,7 @@ const getArgType = (arg: string) => { } const Contract: NextPage = () => { + const { format } = useFormatIntl() const router = useRouter() const address = router.query?.address as string const { isLoading, startLoading, endLoading } = useLoading() @@ -277,17 +279,17 @@ const Contract: NextPage = () => { - + - + - + @@ -300,7 +302,7 @@ const Contract: NextPage = () => { {contract?.metadata && ( <> - Contract ABI Verified + {format('contract_abi_verified')} )} @@ -321,7 +323,7 @@ const Contract: NextPage = () => { @@ -350,7 +352,7 @@ const Contract: NextPage = () => { {query?.args?.length > 0 && ( - Method Arguments + {format('method_arguments')} )} @@ -378,7 +380,7 @@ const Contract: NextPage = () => { className="ink-button ink-button_small" onClick={() => setShowOptions(!showOptions)} > - {showOptions ? 'Hide Options' : 'Show Options'} + {showOptions ? format('hide_options') : format('show_options')} @@ -386,7 +388,7 @@ const Contract: NextPage = () => { <> - gasLimit + {format('gas_limit')} { - storageLimit + {format('storage_limit')} { - value + {format('value')} { <> - Result + {format('result')} @@ -474,7 +476,7 @@ const Contract: NextPage = () => { <> -

No queries found. Try uploading the metadata for this contract.

+

{format('no_queries_found')}

diff --git a/pages/transaction/details/[hash].tsx b/pages/transaction/details/[hash].tsx index f535590..1e2b473 100644 --- a/pages/transaction/details/[hash].tsx +++ b/pages/transaction/details/[hash].tsx @@ -11,8 +11,10 @@ import { useGetTransactionQuery, GetTransactionQuery } from '../../../generated' import { useToast } from '../../../hooks' import { formatTimeAgo } from '../../../lib/utils' import withApollo from '../../../lib/withApollo' +import { useFormatIntl } from '../../../hooks/useFormatIntl' const Transaction: NextPage = () => { + const { format } = useFormatIntl() const router = useRouter() const hash = router.query?.hash as string const [open, setOpen] = useState(false) @@ -39,7 +41,7 @@ const Transaction: NextPage = () => { } onClick={() => setView('Overview')} > - Overview + {format('overview')} @@ -59,7 +61,7 @@ const Transaction: NextPage = () => {

- Summary + {format('summary')}

@@ -68,77 +70,77 @@ const Transaction: NextPage = () => {
AddressLast EventUploaded metadataEvents{format('header_address')}{format('header_last_event')}{format('header_uploaded_metadata')}{format('header_events')}
{getLastEventTime(index)}{contract?.hasMetadata ? 'Yes' : 'No'}{contract?.hasMetadata ? format('yes') : format('no')} {contract?.events?.length}
- + - + - + - + - + - + - + - + - + {open && ( <> - + - + - + - + - + - + - + - + - + @@ -148,7 +150,7 @@ const Transaction: NextPage = () => { )} @@ -158,13 +160,15 @@ const Transaction: NextPage = () => {

- Transaction Receipt Event Logs + {format('transaction_receipt_event_logs')}

{loading && } - {!loading && transaction?.events?.length === 0 &&

No Logs to show

} + {!loading && transaction?.events?.length === 0 && ( +

{format('no_logs_to_show')}

+ )} {transaction?.events?.map((event, index) => ( @@ -177,23 +181,23 @@ const Transaction: NextPage = () => {
- + - + - + - + - + - + diff --git a/pages/transactions.tsx b/pages/transactions.tsx index 2c86d71..6f61b05 100644 --- a/pages/transactions.tsx +++ b/pages/transactions.tsx @@ -10,8 +10,10 @@ import { useGetTransactionsQuery, GetTransactionsQuery } from '../generated' import { useToast } from '../hooks' import { formatTimeAgo, showShortHash } from '../lib/utils' import withApollo from '../lib/withApollo' +import { useFormatIntl } from '../hooks/useFormatIntl' const Transaction: NextPage = () => { + const { format } = useFormatIntl() const [pagination, setPagination] = useState({ skip: 0, take: 10, orderAsc: false }) const { data, loading, error } = useGetTransactionsQuery({ variables: pagination }) const transactions = get(data, 'getTransactions', []) as GetTransactionsQuery['getTransactions'] @@ -45,17 +47,17 @@ const Transaction: NextPage = () => { - + - + - + @@ -64,15 +66,15 @@ const Transaction: NextPage = () => {
Tx Hash{format('header_tx_hash')} {hash}
Block{format('header_block')} {transaction.blockHash}
Timestamp{format('header_timestamp')} {formatTimeAgo(transaction.timestamp)}
Section{format('header_section')} {transaction.section}
Method{format('header_method')} {transaction.method}
Signer{format('header_signer')} {transaction.signer}
Signature{format('header_signature')} {transaction.signature}
Nonce{format('header_nonce')} {transaction.nonce}
Encoded Length{format('header_encoded_length')} {transaction.encodedLength} bytes
Tip{format('header_tip')} {transaction.tip}
Era{format('header_era')} {transaction.era}
Args{format('header_args')} {transaction.args}
callIndex{format('header_callindex')} {transaction.callIndex}
Decimals{format('header_decimals')} {transaction.decimals}
ss58{format('header_ss58')} {transaction.ss58}
Tokens{format('header_tokens')} {transaction.tokens}
Type{format('header_type')} {transaction.type}
Version{format('header_version')} {transaction.version}
Transaction Hash{format('header_transaction_hash')} {event.transactionHash}
Time:{format('header_timestamp')}: {formatTimeAgo(event.timestamp)}
Method:{format('header_method')}: {event.method}
Section:{format('header_section')}: {event.section}
Topics:{format('header_topics')}:
{event.topics @@ -212,7 +216,7 @@ const Transaction: NextPage = () => {
Data:{format('header_data')}: {event.data}
- - + + - - - + + + diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6207a33..b26bfc5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,6 +47,7 @@ specifiers: react-bootstrap: ^2.6.0 react-bootstrap-sidebar-menu: ^2.0.3 react-dom: 18.2.0 + react-intl: ^6.2.1 react-toastify: ^9.1.1 sass: ^1.56.1 tls: ^0.0.1 @@ -78,6 +79,7 @@ dependencies: react-bootstrap: 2.6.0_2zx2umvpluuhvlq44va5bta2da react-bootstrap-sidebar-menu: 2.0.3_2zx2umvpluuhvlq44va5bta2da react-dom: 18.2.0_react@18.2.0 + react-intl: 6.2.1_eetduzquwu67aqoq5644t6dxzu react-toastify: 9.1.1_biqbaboplfbrettd7655fr4n2y sass: 1.56.1 tls: 0.0.1 @@ -830,6 +832,74 @@ packages: - supports-color dev: true + /@formatjs/ecma402-abstract/1.13.0: + resolution: {integrity: sha512-CQ8Ykd51jYD1n05dtoX6ns6B9n/+6ZAxnWUAonvHC4kkuAemROYBhHkEB4tm1uVrRlE7gLDqXkAnY51Y0pRCWQ==} + dependencies: + '@formatjs/intl-localematcher': 0.2.31 + tslib: 2.4.0 + dev: false + + /@formatjs/fast-memoize/1.2.6: + resolution: {integrity: sha512-9CWZ3+wCkClKHX+i5j+NyoBVqGf0pIskTo6Xl6ihGokYM2yqSSS68JIgeo+99UIHc+7vi9L3/SDSz/dWI9SNlA==} + dependencies: + tslib: 2.4.0 + dev: false + + /@formatjs/icu-messageformat-parser/2.1.10: + resolution: {integrity: sha512-KkRMxhifWkRC45dhM9tqm0GXbb6NPYTGVYY3xx891IKc6p++DQrZTnmkVSNNO47OEERLfuP2KkPFPJBuu8z/wg==} + dependencies: + '@formatjs/ecma402-abstract': 1.13.0 + '@formatjs/icu-skeleton-parser': 1.3.14 + tslib: 2.4.0 + dev: false + + /@formatjs/icu-skeleton-parser/1.3.14: + resolution: {integrity: sha512-7bv60HQQcBb3+TSj+45tOb/CHV5z1hOpwdtS50jsSBXfB+YpGhnoRsZxSRksXeCxMy6xn6tA6VY2601BrrK+OA==} + dependencies: + '@formatjs/ecma402-abstract': 1.13.0 + tslib: 2.4.0 + dev: false + + /@formatjs/intl-displaynames/6.1.4: + resolution: {integrity: sha512-sEbziGLsWQo6nA8ZUBcsDRlZzPg+uMVjDmbTalgGqRWLbdXuxMldTYdaCK+UptyJhkmNVM/erz3csTiyqamXHQ==} + dependencies: + '@formatjs/ecma402-abstract': 1.13.0 + '@formatjs/intl-localematcher': 0.2.31 + tslib: 2.4.0 + dev: false + + /@formatjs/intl-listformat/7.1.3: + resolution: {integrity: sha512-rs0Kxl78PeRCedx2cmFoBqcun2Kf0bCQrF8ycna54sfePpDhMskvODWeI4G/xBioW01FjK7CJSvtJJ87hrr79A==} + dependencies: + '@formatjs/ecma402-abstract': 1.13.0 + '@formatjs/intl-localematcher': 0.2.31 + tslib: 2.4.0 + dev: false + + /@formatjs/intl-localematcher/0.2.31: + resolution: {integrity: sha512-9QTjdSBpQ7wHShZgsNzNig5qT3rCPvmZogS/wXZzKotns5skbXgs0I7J8cuN0PPqXyynvNVuN+iOKhNS2eb+ZA==} + dependencies: + tslib: 2.4.0 + dev: false + + /@formatjs/intl/2.5.1_typescript@4.9.3: + resolution: {integrity: sha512-P01ZGuDDlcN8bHHBCEHspJPvs8WJeO8SXlUIcVGWhS3IN5vUgz0QKUXcKBFnJbEHhONJ+azlObVwvlDKsE+kUg==} + peerDependencies: + typescript: ^4.7 + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@formatjs/ecma402-abstract': 1.13.0 + '@formatjs/fast-memoize': 1.2.6 + '@formatjs/icu-messageformat-parser': 2.1.10 + '@formatjs/intl-displaynames': 6.1.4 + '@formatjs/intl-listformat': 7.1.3 + intl-messageformat: 10.2.1 + tslib: 2.4.0 + typescript: 4.9.3 + dev: false + /@graphql-codegen/add/3.2.1_graphql@16.6.0: resolution: {integrity: sha512-w82H/evh8SSGoD3K6K/Oh3kqSdbuU+TgHqMYmmHFxtH692v2xhN/cu1s/TotBQ7r4mO7OQutze7dde2tZEXGEQ==} peerDependencies: @@ -2655,6 +2725,13 @@ packages: '@types/node': 16.18.3 dev: true + /@types/hoist-non-react-statics/3.3.1: + resolution: {integrity: sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==} + dependencies: + '@types/react': 18.0.25 + hoist-non-react-statics: 3.3.2 + dev: false + /@types/istanbul-lib-coverage/2.0.4: resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} dev: true @@ -5141,6 +5218,15 @@ packages: side-channel: 1.0.4 dev: true + /intl-messageformat/10.2.1: + resolution: {integrity: sha512-1lrJG2qKzcC1TVzYu1VuB1yiY68LU5rwpbHa2THCzA67Vutkz7+1lv5U20K3Lz5RAiH78zxNztMEtchokMWv8A==} + dependencies: + '@formatjs/ecma402-abstract': 1.13.0 + '@formatjs/fast-memoize': 1.2.6 + '@formatjs/icu-messageformat-parser': 2.1.10 + tslib: 2.4.0 + dev: false + /invariant/2.2.4: resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} dependencies: @@ -6947,6 +7033,29 @@ packages: react: 18.2.0 dev: true + /react-intl/6.2.1_eetduzquwu67aqoq5644t6dxzu: + resolution: {integrity: sha512-hYxcSamgoA3Mvc55nwhTF1v15T0NUSkaV/EScMNVZXg0kRyaMAoNHkCi9/9H+TnXWNiWrcWH9bjlMlJwrG2V7g==} + peerDependencies: + react: ^16.6.0 || 17 || 18 + typescript: ^4.7 + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@formatjs/ecma402-abstract': 1.13.0 + '@formatjs/icu-messageformat-parser': 2.1.10 + '@formatjs/intl': 2.5.1_typescript@4.9.3 + '@formatjs/intl-displaynames': 6.1.4 + '@formatjs/intl-listformat': 7.1.3 + '@types/hoist-non-react-statics': 3.3.1 + '@types/react': 18.0.25 + hoist-non-react-statics: 3.3.2 + intl-messageformat: 10.2.1 + react: 18.2.0 + tslib: 2.4.0 + typescript: 4.9.3 + dev: false + /react-is/16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} @@ -7634,6 +7743,10 @@ packages: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} dev: true + /tslib/2.4.0: + resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} + dev: false + /tslib/2.4.1: resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} @@ -7702,7 +7815,6 @@ packages: resolution: {integrity: sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==} engines: {node: '>=4.2.0'} hasBin: true - dev: true /ua-parser-js/0.7.32: resolution: {integrity: sha512-f9BESNVhzlhEFf2CHMSj40NWOjYPl1YKYbrvIr/hFTDEmLq7SRbWvm7FcdcpCYT95zrOhC7gZSxjdnnTpBcwVw==} From a403ddb260c5c84bce29a4248a64403c38a874f2 Mon Sep 17 00:00:00 2001 From: Ruben Gutierrez Date: Fri, 18 Nov 2022 10:41:27 -0400 Subject: [PATCH 02/13] swith language btn --- assets/img/language.svg | 1 + components/Header/Header.tsx | 25 +++++++++++++++++++++++-- i18n/en.ts | 3 +++ i18n/es.ts | 6 +++--- 4 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 assets/img/language.svg diff --git a/assets/img/language.svg b/assets/img/language.svg new file mode 100644 index 0000000..2a6b4a9 --- /dev/null +++ b/assets/img/language.svg @@ -0,0 +1 @@ +ionicons-v5-l \ No newline at end of file diff --git a/components/Header/Header.tsx b/components/Header/Header.tsx index 51f5110..dcb6098 100644 --- a/components/Header/Header.tsx +++ b/components/Header/Header.tsx @@ -1,10 +1,13 @@ import { useRouter } from 'next/router' import { useEffect, useState } from 'react' -import { Col, Row } from 'react-bootstrap' +import { Col, Dropdown, DropdownButton, InputGroup, Row } from 'react-bootstrap' import { useFormatIntl } from '../../hooks/useFormatIntl' import { getTitle } from '../../utils/pagetitile' import InfoCard from '../InfoCard/InfoCard' import Searchbar from '../SearchBar/SearchBar' +import LanguageIcon from '../../assets/img/language.svg' +import Image from 'next/image' +import Link from 'next/link' export const Header = () => { const { format } = useFormatIntl() @@ -17,8 +20,26 @@ export const Header = () => { return ( <> -
+
+ + } + id="input-group-dropdown-1" + > + + + {format('english')} + + + + + {format('spanish')} + + + +
diff --git a/i18n/en.ts b/i18n/en.ts index 198726f..1323572 100644 --- a/i18n/en.ts +++ b/i18n/en.ts @@ -87,4 +87,7 @@ export const en = { no_extension_installed: 'No extension installed!', contract_metadata_not_found: 'Contract metadata not found', query_not_found: 'Query/Transaction method not found', + + english: 'English', + spanish: 'Spanish', } diff --git a/i18n/es.ts b/i18n/es.ts index 4e74b2c..9c922fc 100644 --- a/i18n/es.ts +++ b/i18n/es.ts @@ -1,7 +1,7 @@ export const es = { - blocks: 'Blocks', - transactions: 'Transactions', - contracts: 'Contracts', + blocks: 'Bloques', + transactions: 'Transacciones', + contracts: 'Contratos', search_by: 'Search by...', transaction_hash: 'Transaction Hash', block_hash: 'Block Hash', From bbd5033b3cc597ccebb9b3d7c11d34f8a4e925cc Mon Sep 17 00:00:00 2001 From: Ruben Gutierrez Date: Fri, 18 Nov 2022 11:33:11 -0400 Subject: [PATCH 03/13] update spanish translations --- components/Sidebar/Sidebar.tsx | 4 +- hooks/useToast.tsx | 5 +- i18n/en.ts | 5 +- i18n/es.ts | 118 ++++++++++++++----------- pages/contracts/contract/[address].tsx | 18 ++-- 5 files changed, 86 insertions(+), 64 deletions(-) diff --git a/components/Sidebar/Sidebar.tsx b/components/Sidebar/Sidebar.tsx index 8778b3f..fae2993 100644 --- a/components/Sidebar/Sidebar.tsx +++ b/components/Sidebar/Sidebar.tsx @@ -6,8 +6,10 @@ import { Nav } from 'react-bootstrap' import logo from '../../assets/img/logo.svg' import { Sidebar } from '../../interfaces/sidebar' import Menu from '../../json/Sidebar.json' +import { useFormatIntl } from '../../hooks/useFormatIntl' function Navbar() { + const { format } = useFormatIntl() const [dataJson, setMenu] = useState([]) const router = useRouter() @@ -35,7 +37,7 @@ function Navbar() { alt={item.label} className="ink_sidebar-icon" />{' '} - {item.label} + {item.label ? format(item.label?.toLowerCase()) : ''} diff --git a/hooks/useToast.tsx b/hooks/useToast.tsx index b982e6a..8ef96d5 100644 --- a/hooks/useToast.tsx +++ b/hooks/useToast.tsx @@ -1,4 +1,5 @@ import { toast } from 'react-toastify' +import { useFormatIntl } from './useFormatIntl' const toastCommonProps = { style: { @@ -8,6 +9,8 @@ const toastCommonProps = { } export const useToast = () => { + const { format } = useFormatIntl() + const showSuccessToast = (message: string) => { toast.dismiss() toast.success(message, { @@ -26,7 +29,7 @@ export const useToast = () => { const showLoadingToast = () => { toast.dismiss() - toast.loading('Loading', { + toast.loading(format('loading'), { autoClose: false, toastId: 'toast-loading', ...toastCommonProps, diff --git a/i18n/en.ts b/i18n/en.ts index 1323572..a198217 100644 --- a/i18n/en.ts +++ b/i18n/en.ts @@ -39,8 +39,8 @@ export const en = { header_tokens: 'Tokens', header_type: 'Type', header_version: 'Version', - header_more: 'Version', - header_topics: 'Version', + header_more: 'More', + header_topics: 'Topics', header_data: 'Data', overview: 'Overview', @@ -61,7 +61,6 @@ export const en = { contract_abi_verified: 'Contract ABI Verified', - methos_arguments: 'Method Arguments', show_options: 'Show Options', hide_options: 'Hide options', gast_limit: 'gasLimit', diff --git a/i18n/es.ts b/i18n/es.ts index 9c922fc..f2771ac 100644 --- a/i18n/es.ts +++ b/i18n/es.ts @@ -2,73 +2,91 @@ export const es = { blocks: 'Bloques', transactions: 'Transacciones', contracts: 'Contratos', - search_by: 'Search by...', - transaction_hash: 'Transaction Hash', - block_hash: 'Block Hash', - contract_address: 'Contract Address', - search_placeholder: 'Contract Address, Tx Hash, Block Hash', - lastest_block: 'Lastest Block', + search_by: 'Buscar por...', + transaction_hash: 'Hash de la transacción', + block_hash: 'Hash del bloque', + contract_address: 'Dirección del contrato', + search_placeholder: 'Dirección, Hash', + lastest_block: 'Ultimo bloque', - header_number: 'Number', + header_number: 'Número', header_hash: 'Hash', - header_time: 'Time', - header_parent_hash: 'Parent Hash', - header_transactions: 'Transactions', - header_size: 'Size', - header_method: 'Method', - header_signer: 'Signer', - header_address: 'Address', - header_last_event: 'Last Event', - header_uploaded_metadata: 'Uploaded metadata', - header_events: 'Events', - header_timestamp: 'Timestamp', - header_parent: 'Parent', - header_tx_hash: 'Tx Hash', - header_block: 'Block', - header_section: 'Section', - header_signature: 'Signature', + header_block_hash: 'Hash del bloque', + header_time: 'Tiempo', + header_parent_hash: 'Hash del padre', + header_transactions: 'Transacciones', + header_size: 'Tamaño', + header_method: 'Método', + header_signer: 'Autor', + header_address: 'Dirección', + header_last_event: 'Ultimo evento', + header_uploaded_metadata: 'Metadata subida', + header_events: 'Eventos', + header_timestamp: 'Marca de tiempo', + header_parent: 'Padre', + header_tx_hash: 'Hash de la transacción', + header_block: 'Bloque', + header_section: 'Sección', + header_signature: 'Firma', header_nonce: 'Nonce', - header_encoded_length: 'Encoded Length', + header_encoded_length: 'Longitud codificada', header_tip: 'Tip', header_era: 'Era', header_args: 'Args', - header_callIndex: 'callindex', - header_decimals: 'decimals', + header_callindex: 'callindex', + header_decimals: 'decimales', header_ss58: 'ss58', header_tokens: 'Tokens', - header_type: 'Type', - header_version: 'Version', - header_more: 'Version', - header_topics: 'Version', + header_type: 'Tipo', + header_version: 'Versión', + header_more: 'More', + header_topics: 'Tópicos', header_data: 'Data', - show_more: 'Show more', + overview: 'Resumen', + logs: 'Registros', - transaction_receipt_event_logs: 'Transaction Receipt Event Logs', - no_logs_to_show: 'No Logs to show', + show_more: 'Mostrar más', + show_less: 'Mostrat menos', - contract_abi: 'Contract ABI', - upload_abi: 'Upload ABI', - run_contract_methods: 'Run contract methods', + yes: 'Sí', + no: 'No', - contract_abi_verified: 'Contract ABI Verified', + transaction_receipt_event_logs: 'Registros de eventos de recepción de transacciones', + no_logs_to_show: 'No existen registros para mostrar', - methos_arguments: 'Method Arguments', - show_options: 'Show Options', - gast_limit: 'gasLimit', - storage_limit: 'Storage Limit', - value: 'value', + contract_abi: 'ABI del contrato', + upload_abi: 'Subir ABI', + run_contract_methods: 'Ejecutar métodos del contrato', - upload_placeholder: 'Please upload the metadata of the contract in a Base64 encoded format.', - upload: 'Upload', + contract_abi_verified: 'Contrato ABI Verificado', - no_queries_found: 'No queries found. Try uploading the metadata for this contract.', + show_options: 'Ver Opciones', + hide_options: 'Ocultar Opciones', + gast_limit: 'límite de gas', + storage_limit: 'límite de almacenamiento', + value: 'valor', - loading: 'Loading', - successfull_upload: 'Successfull Upload', + contract: 'Contrato', + events: 'Eventos', + upload_placeholder: 'Por favor, cargue los metadatos del contrato en un formato codificado en Base64.', + upload: 'Cargar', + result: 'Resultado', + no_queries_found: 'No se han encontrado consultas. Intente cargar los metadatos de este contrato.', + method_arguments: 'Argumentos del método', - not_found: 'Not found', - summary: 'Summary', + loading: 'Cargando', + successfull_upload: 'Carga exitosa', - send: 'send', + not_found: 'No encontrado', + summary: 'Resumen', + + send: 'enviar', + + no_extension_installed: 'Extensión no instalada', + contract_metadata_not_found: 'Metadata del contrato no encontrada', + query_not_found: 'Método de Consulta/Transacción no encontrado', + + english: 'Inglés', + spanish: 'Español', } diff --git a/pages/contracts/contract/[address].tsx b/pages/contracts/contract/[address].tsx index 80a4fbc..59e225b 100644 --- a/pages/contracts/contract/[address].tsx +++ b/pages/contracts/contract/[address].tsx @@ -147,7 +147,7 @@ const Contract: NextPage = () => { showLoadingToast() try { await uploadMetadataMutation({ variables: { contractAddress: address, metadata: base64Abi } }) - showSuccessToast('Successful upload') + showSuccessToast(format('successful_upload')) setBase64Abi('') refetch() } catch (error) { @@ -161,7 +161,7 @@ const Contract: NextPage = () => { const { web3Accounts, web3Enable, web3FromAddress } = extension const extensions = await web3Enable('Ink! Explorer') if (extensions?.length === 0) { - showErrorToast('No extension installed!') + showErrorToast(format('no_extension_installed')) return } const accounts = await web3Accounts() @@ -180,12 +180,12 @@ const Contract: NextPage = () => { const api = await connect(WS_PROVIDER) const { metadata } = contract || {} if (!metadata) { - throw new Error('Contract metadata not found') + throw new Error(format('contract_metadata_not_found')) } const abi = new Abi(metadata) const { query, tx } = getContractInstance(api, abi, address, method) if (!query || !tx) { - throw new Error('Query/Transaction method not found') + throw new Error(format('query_not_found')) } const values: string[] = Object.values(parameters[method]) || [] if (query?.meta?.isMutating) { @@ -296,7 +296,7 @@ const Contract: NextPage = () => { - + {contract?.metadata && ( @@ -311,13 +311,13 @@ const Contract: NextPage = () => { className="form-control" rows={15} placeholder="No metadata found. Upload your contract metadata to verify your contract." - value={contract?.metadata || 'Not found'} + value={contract?.metadata || format('not_found')} readOnly > - +
HashBlock Hash{format('header_hash')}{format('header_block_hash')} toogleOrder()} role="button" className="d-flex align-center gap-1"> - Time + {format('header_time')} SectionMethodSigner{format('header_section')}{format('header_method')}{format('header_signer')}