From ae661226bf51296e4406d60b93ff7712f4bb4294 Mon Sep 17 00:00:00 2001 From: TITI <162849030+0xtiti@users.noreply.github.com> Date: Mon, 22 Jul 2024 17:51:48 -0300 Subject: [PATCH 1/2] feat: format number (#5) closes ZKS-111 --- src/components/Table.tsx | 3 +- src/components/TotalValueLocked.tsx | 4 ++- src/containers/LockedAssets/index.tsx | 3 +- src/data/ecosystemMockData.json | 2 +- src/utils/format.ts | 43 +++++++++++++++++++++++++++ 5 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/components/Table.tsx b/src/components/Table.tsx index 2be096b..4aec5f6 100644 --- a/src/components/Table.tsx +++ b/src/components/Table.tsx @@ -1,6 +1,7 @@ import { useTranslation } from 'next-i18next'; import { EcosystemChainData } from '~/types'; +import { formatDataNumber } from '~/utils'; interface TableProps { chains: EcosystemChainData[]; @@ -25,7 +26,7 @@ export const Table = ({ chains }: TableProps) => { {data.name} {data.id} {data.nativeToken} - {data.tvl} + {formatDataNumber(data.tvl, 0, true)} {data.type} ); diff --git a/src/components/TotalValueLocked.tsx b/src/components/TotalValueLocked.tsx index 38b4fe1..bc502c9 100644 --- a/src/components/TotalValueLocked.tsx +++ b/src/components/TotalValueLocked.tsx @@ -1,3 +1,5 @@ +import { formatDataNumber } from '~/utils'; + export interface TokenValueLocked { token: string; value: number; @@ -13,7 +15,7 @@ export const TotalValueLocked = ({ tvl }: TotalValueLockedProps) => { {tvl.map((data, index) => (
{data.token} - {data.value} + {formatDataNumber(data.value, 0, true)}
))} diff --git a/src/containers/LockedAssets/index.tsx b/src/containers/LockedAssets/index.tsx index beb9cc6..3d0212d 100644 --- a/src/containers/LockedAssets/index.tsx +++ b/src/containers/LockedAssets/index.tsx @@ -2,6 +2,7 @@ import { useTranslation } from 'next-i18next'; import { TotalValueLocked, Title } from '~/components'; import { useData } from '~/hooks'; +import { formatDataNumber } from '~/utils'; export const LockedAssets = () => { const { t } = useTranslation(); @@ -11,7 +12,7 @@ export const LockedAssets = () => {
{ecosystemData && ( <> - + <Title title={`${t('HOME.lockedAssets')}: ${formatDataNumber(ecosystemData.total, 0, true, true)}`} /> <TotalValueLocked tvl={ecosystemData.tvl} /> </> )} diff --git a/src/data/ecosystemMockData.json b/src/data/ecosystemMockData.json index c701642..acb7d40 100644 --- a/src/data/ecosystemMockData.json +++ b/src/data/ecosystemMockData.json @@ -50,7 +50,7 @@ "type": "Validium" } ], - "total": 7000000, + "total": 700000000, "tvl": [ { "token": "ETH", diff --git a/src/utils/format.ts b/src/utils/format.ts index d650ed3..1b39c3d 100644 --- a/src/utils/format.ts +++ b/src/utils/format.ts @@ -1,3 +1,46 @@ export const truncateAddress = (address: string) => { return `${address.slice(0, 6)}...${address.slice(-4)}`; }; + +export function formatDataNumber(input: string | number, formatDecimal = 3, currency?: boolean, compact?: boolean) { + const res: number = Number.parseFloat(input.toString()); + + if (res === 0 || isNaN(res)) return `${currency ? '$0' : '0'}`; + + if (res < 0.01) return formatSmallNumber(res); + + const userNotation = compact ? 'compact' : 'standard'; + const notation = res > 1e12 ? 'scientific' : userNotation; + + return new Intl.NumberFormat('en-US', { + maximumFractionDigits: formatDecimal, + notation: notation, + style: currency ? 'currency' : 'decimal', + currency: 'USD', + }).format(res); +} + +export const formatSmallNumber = (value: number) => { + if (value === 0) { + return '0'; + } + + const formattedValue = value.toString(); + + let numLeadingZeros = 0; + + // Count the leading zeros and decimal point + for (let i = 0; i < formattedValue.length; i++) { + if (formattedValue[i] === '0' || formattedValue[i] === '.') { + numLeadingZeros++; + } else { + break; + } + } + + // Return the number with 3 digits after the last leading zero + const result = formattedValue.slice(0, numLeadingZeros + 3); + + // Trim any trailing zeros from the result + return result.replace(/\.?0+$/, ''); +}; From 9669d7f9e5f21cee3c33bac5a90418218206488e Mon Sep 17 00:00:00 2001 From: TITI <162849030+0xtiti@users.noreply.github.com> Date: Mon, 22 Jul 2024 17:52:02 -0300 Subject: [PATCH 2/2] feat: search chain by id (#8) closes ZKS-112 --- public/locales/en/common.json | 3 ++- public/locales/es/common.json | 3 ++- src/components/NotFound.tsx | 11 +++++++++++ src/components/index.ts | 1 + src/containers/Dashboard/index.tsx | 23 ++++++++++++++++------- 5 files changed, 32 insertions(+), 9 deletions(-) create mode 100644 src/components/NotFound.tsx diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 5451f12..58bc09c 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -11,7 +11,8 @@ "nativeToken": "Native token", "tvl": "TVL - L1", "type": "Type", - "search": "Search by chain name or id..." + "search": "Search by chain name or id...", + "notFound": "Chain not found" } }, "CHAINPAGE": { diff --git a/public/locales/es/common.json b/public/locales/es/common.json index 6c8e324..f85b9a8 100644 --- a/public/locales/es/common.json +++ b/public/locales/es/common.json @@ -11,7 +11,8 @@ "nativeToken": "Token nativo", "tvl": "TVL - L1", "type": "Tipo", - "search": "Buscar por nombre o ID de la cadena..." + "search": "Buscar por nombre o ID de la cadena...", + "notFound": "Cadena no encontrada" } }, "CHAINPAGE": { diff --git a/src/components/NotFound.tsx b/src/components/NotFound.tsx new file mode 100644 index 0000000..358cdd8 --- /dev/null +++ b/src/components/NotFound.tsx @@ -0,0 +1,11 @@ +interface NotFoundProps { + text: string; +} + +export const NotFound = ({ text }: NotFoundProps) => { + return ( + <div> + <p>{text}</p> + </div> + ); +}; diff --git a/src/components/index.ts b/src/components/index.ts index e2912ee..7657955 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -6,3 +6,4 @@ export * from './SearchBar'; export * from './TotalValueLocked'; export * from './Title'; export * from './TitleBanner'; +export * from './NotFound'; diff --git a/src/containers/Dashboard/index.tsx b/src/containers/Dashboard/index.tsx index eb023e4..8410897 100644 --- a/src/containers/Dashboard/index.tsx +++ b/src/containers/Dashboard/index.tsx @@ -1,7 +1,7 @@ import { useTranslation } from 'next-i18next'; import { useState } from 'react'; -import { SearchBar, Table, Title } from '~/components'; +import { NotFound, SearchBar, Table, Title } from '~/components'; import { useData } from '~/hooks'; export const Dashboard = () => { @@ -9,15 +9,23 @@ export const Dashboard = () => { const { ecosystemData } = useData(); const [searchTerm, setSearchTerm] = useState<string>(''); + const filteredChains = ecosystemData?.chains.filter((chain) => { + const chainIdStr = String(chain.id); + const formattedSearchTerm = String(searchTerm).toLowerCase(); + + // Check if either chain name or chain ID matches the search term + const matchesName = chain.name.toLowerCase().includes(formattedSearchTerm); + const matchesId = chainIdStr.includes(formattedSearchTerm); + + return matchesName || matchesId; + }); + + const availableChains = filteredChains?.length > 0; + const handleChange = (value: string) => { setSearchTerm(value); }; - // Filter chains based on search term - const filteredChains = ecosystemData?.chains.filter((chain) => - chain.name.toLowerCase().includes(searchTerm.toLowerCase()), - ); - return ( <section> <header> @@ -25,7 +33,8 @@ export const Dashboard = () => { <SearchBar value={searchTerm} onChange={handleChange} /> </header> - <Table chains={filteredChains} /> + {availableChains && <Table chains={filteredChains} />} + {!availableChains && <NotFound text={t('HOME.DASHBOARD.notFound')} />} </section> ); };