Merge pull request #7 from jejolare-dev/dev

feature: render token images
This commit is contained in:
Dmitrii Kolpakov 2025-08-12 20:13:40 +07:00 committed by GitHub
commit d1e935ff9d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 74 additions and 38 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

BIN
public/tokens/token.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,26 @@
'use client';
import { useState, useEffect } from 'react';
import Image, { ImageProps } from 'next/image';
type ImgWithFallbackProps = ImageProps & {
fallbackSrc?: string;
alt: string;
};
const ImgWithFallback = ({
src,
alt,
fallbackSrc = '/tokens/token.png',
...rest
}: ImgWithFallbackProps) => {
const [imgSrc, setImgSrc] = useState(src);
useEffect(() => {
setImgSrc(src);
}, [src]);
return <Image {...rest} alt={alt} src={imgSrc} onError={() => setImgSrc(fallbackSrc)} />;
};
export default ImgWithFallback;

View file

@ -5,6 +5,7 @@ import { ReactComponent as ArrowRight } from '@/assets/images/UI/arrow_right.svg
import { Store } from '@/store/store-reducer';
import PairData from '@/interfaces/common/PairData';
import { notationToString, roundTo, tradingKnownCurrencies } from '@/utils/utils';
import ImgWithFallback from '@/components/UI/ImgWithFallback';
import styles from './PairsCard.module.scss';
interface IProps {
@ -51,10 +52,10 @@ export default function PairsCard({ pair }: IProps) {
return (
<div className={styles.card}>
<div className={styles.card__header}>
<Image
<ImgWithFallback
width={18}
height={18}
src={`/currencies/trade_${code}.svg`}
src={`/tokens/${firstCurrency.asset_id}.png`}
alt="currency"
/>
<div className={styles.currency_name}>

View file

@ -1,3 +1,4 @@
// PairsTable.tsx
import { memo, useContext, useMemo } from 'react';
import { ColumnDef, flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table';
import { useRouter } from 'next/router';
@ -7,29 +8,9 @@ import { Store } from '@/store/store-reducer';
import PairData from '@/interfaces/common/PairData';
import { ContextState } from '@/interfaces/common/ContextValue';
import { tradingKnownCurrencies, roundTo, notationToString } from '@/utils/utils';
import ImgWithFallback from '@/components/UI/ImgWithFallback';
import styles from './PairsTable.module.scss';
type Currency = {
code: string;
name: string;
whitelisted?: boolean;
featured?: boolean;
};
type Row = {
id: string;
pair: {
base: Currency;
quote: Currency;
};
price: number;
priceUSD: string;
change: number;
volume: number;
volumeUSD: string;
featured: boolean;
code: string;
};
import { Row } from './types';
function transformPairsToRows(pairs: PairData[], state: ContextState): Row[] {
return pairs.map((pair) => {
@ -38,17 +19,18 @@ function transformPairsToRows(pairs: PairData[], state: ContextState): Row[] {
const price = Number(roundTo(notationToString(pair.rate ?? 0)));
const currentPriceUSD = secondAssetUsdPrice ? price : 0;
const priceUSD = currentPriceUSD
? String(`$${(secondAssetUsdPrice * price).toFixed(2)}`)
: String(`$${(secondAssetUsdPrice * price).toFixed(0)}`);
? `$${(secondAssetUsdPrice * price).toFixed(2)}`
: `$${(secondAssetUsdPrice * price).toFixed(0)}`;
const volume = Number(roundTo(notationToString(pair.volume ?? 0)));
const currentVolumeUSD = secondAssetUsdPrice ? volume : 0;
const volumeUSD = currentVolumeUSD
? String(`$${(secondAssetUsdPrice * volume).toFixed(2)}`)
: String(`$${(secondAssetUsdPrice * volume).toFixed(0)}`);
? `$${(secondAssetUsdPrice * volume).toFixed(2)}`
: `$${(secondAssetUsdPrice * volume).toFixed(0)}`;
return {
id: pair.id,
assetId: pair.first_currency.asset_id,
pair: {
base: pair.first_currency,
quote: pair.second_currency,
@ -74,6 +56,10 @@ function PairsTable({ data }: IProps) {
const router = useRouter();
const { state } = useContext(Store);
const rows = useMemo(() => {
return transformPairsToRows(data, state);
}, [data, state.assetsRates]);
const columns = useMemo<ColumnDef<Row>[]>(
() => [
{
@ -82,15 +68,15 @@ function PairsTable({ data }: IProps) {
cell: ({ row }) => {
const {
pair: { base, quote },
code,
featured,
assetId,
} = row.original;
return (
<div className={styles.pair_cell}>
<Image
<ImgWithFallback
width={18}
height={18}
src={`/currencies/trade_${code}.svg`}
src={`/tokens/${assetId}.png`}
alt="currency"
/>
<div className={styles.currency_name}>
@ -114,9 +100,8 @@ function PairsTable({ data }: IProps) {
{
accessorKey: 'price',
header: ({ table }) => {
const row = table.options.data[0] as Row;
const name = row?.pair.quote.name;
const row0 = table.options.data[0] as Row | undefined;
const name = row0?.pair.quote.name;
return `Price ${name ? `(${name})` : ''}`;
},
cell: ({ row }) => (
@ -186,13 +171,14 @@ function PairsTable({ data }: IProps) {
),
},
],
[],
[router],
);
const table = useReactTable({
data: transformPairsToRows(data, state),
data: rows,
columns,
getCoreRowModel: getCoreRowModel(),
getRowId: (r) => r.id,
});
return (

View file

@ -0,0 +1,22 @@
type Currency = {
code: string;
name: string;
whitelisted?: boolean;
featured?: boolean;
};
export type Row = {
id: string;
assetId: string | undefined | null;
pair: {
base: Currency;
quote: Currency;
};
price: number;
priceUSD: string;
change: number;
volume: number;
volumeUSD: string;
featured: boolean;
code: string;
};

View file

@ -56,6 +56,7 @@ import LightningImg from '@/assets/images/UI/lightning.png';
import RocketImg from '@/assets/images/UI/rocket.png';
import { ReactComponent as ConnectionIcon } from '@/assets/images/UI/connection.svg';
import Image from 'next/image';
import ImgWithFallback from '@/components/UI/ImgWithFallback';
import CandleChart from './CandleChart/CandleChart';
import OrdersBuySellSwitch from './OrdersBuySellSwitch/OrdersBuySellSwitch';
import InputPanelItem from './InputPanelItem/InputPanelItem';
@ -1054,10 +1055,10 @@ function Trading() {
<div className={styles.trading__currency__wrapper}>
<div className={styles.trading__currency__wrapper_top}>
<div>
<Image
<ImgWithFallback
width={50}
height={50}
src={`/currencies/trade_${imgCode}.svg`}
src={`/tokens/${pairData?.first_currency.asset_id}.png`}
alt="currency"
/>
</div>