Skip to content

Commit

Permalink
Simplify and streamline icon definition
Browse files Browse the repository at this point in the history
  • Loading branch information
TorstenStueber committed Aug 20, 2024
1 parent 8095411 commit b82a70f
Show file tree
Hide file tree
Showing 9 changed files with 63 additions and 106 deletions.
32 changes: 6 additions & 26 deletions src/components/AssetNumericInput/index.tsx
Original file line number Diff line number Diff line change
@@ -1,48 +1,29 @@
import { FC, useMemo } from 'preact/compat';
import { UseFormRegisterReturn } from 'react-hook-form';
import { ConnectButton } from '@rainbow-me/rainbowkit';
import { InputTokenType, OutputTokenType } from '../../constants/tokenConfig';
import { AssetButton } from '../buttons/AssetButton';
import { SwapFormValues } from '../Nabla/schema';
import { NumericInput } from '../NumericInput';

export const ChainName = () => (
<ConnectButton.Custom>
{({ account, chain, openChainModal, openConnectModal, authenticationStatus, mounted }) => {
const ready = mounted && authenticationStatus !== 'loading';
const connected =
ready && account && chain && (!authenticationStatus || authenticationStatus === 'authenticated');

return (
<button type="button" className="text-sm text-blue-700" onClick={connected ? openChainModal : openConnectModal}>
{chain?.name || 'Select chain'}
</button>
);
}}
</ConnectButton.Custom>
);
import { AssetIconType } from '../../hooks/useGetIcon';

interface AssetNumericInputProps {
tokenType?: InputTokenType | OutputTokenType | 'eur';
tokenSymbol?: string;
assetIcon: AssetIconType;
tokenSymbol: string;
onClick: () => void;
additionalText?: string;
disabled?: boolean;
readOnly?: boolean;
registerInput: UseFormRegisterReturn<keyof SwapFormValues>;
}

export const AssetNumericInput: FC<AssetNumericInputProps> = ({
additionalText,
tokenType,
assetIcon,
tokenSymbol,
onClick,
registerInput,
...rest
}) => {
const memoizedAssetButton = useMemo(
() => <AssetButton tokenType={tokenType} tokenSymbol={tokenSymbol} onClick={onClick} />,
[tokenType, tokenSymbol, onClick],
() => <AssetButton assetIcon={assetIcon} tokenSymbol={tokenSymbol} onClick={onClick} />,
[assetIcon, tokenSymbol, onClick],
);

return (
Expand All @@ -55,7 +36,6 @@ export const AssetNumericInput: FC<AssetNumericInputProps> = ({
<div className="flex items-center justify-between">
{memoizedAssetButton}
<div className="w-2"></div>
{additionalText ? <p className="text-sm text-blue-700">{additionalText}</p> : <ChainName />}
</div>

<NumericInput
Expand Down
6 changes: 3 additions & 3 deletions src/components/ExchangeRate/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import { InputTokenDetails } from '../../constants/tokenConfig';
import { UseTokenOutAmountResult } from '../../hooks/nabla/useTokenAmountOut';

interface ExchangeRateProps {
fromToken?: InputTokenDetails;
toTokenSymbol?: string;
fromToken: InputTokenDetails;
toTokenSymbol: string;
tokenOutData: UseTokenOutAmountResult;
}

export const ExchangeRate: FC<ExchangeRateProps> = ({ tokenOutData, fromToken, toTokenSymbol }) => {
const exchangeRate =
fromToken !== undefined && toTokenSymbol !== undefined && !tokenOutData.isLoading && tokenOutData.data ? (
fromToken !== undefined && !tokenOutData.isLoading && tokenOutData.data ? (
<>{`1 ${fromToken.assetSymbol} = ${Number(tokenOutData.data.effectiveExchangeRate).toFixed(
2,
)} ${toTokenSymbol}`}</>
Expand Down
2 changes: 1 addition & 1 deletion src/components/FeeCollapse/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ function calculateFeesUSD(fromAmount: string): string {
interface CollapseProps {
fromAmount?: string;
toAmount?: string;
toTokenSymbol?: string;
toTokenSymbol: string;
}

export const FeeCollapse: FC<CollapseProps> = ({ fromAmount, toAmount, toTokenSymbol }) => {
Expand Down
16 changes: 7 additions & 9 deletions src/components/InputKeys/PoolListItem/index.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
import { Avatar, AvatarProps, Button } from 'react-daisyui';
import { CheckIcon } from '@heroicons/react/20/solid';
import { useGetIcon } from '../../../hooks/useGetIcon';
import { Fiat, InputTokenType, OutputTokenType } from '../../../constants/tokenConfig';
import { AssetIconType, useGetIcon } from '../../../hooks/useGetIcon';
import { InputTokenType, OutputTokenType } from '../../../constants/tokenConfig';

interface PoolListItemProps<T extends InputTokenType | OutputTokenType> {
tokenType: T;
tokenSymbol: string;
isSelected?: boolean;
onSelect: (tokenType: T) => void;
fiat?: Fiat;
assetIcon: AssetIconType;
}

export function PoolListItem<T extends InputTokenType | OutputTokenType>({
tokenType,
tokenSymbol,
isSelected,
onSelect,
fiat,
assetIcon,
}: PoolListItemProps<T>) {
const formattedTokenType = fiat ? fiat.symbol : tokenType;
const formattedTokenSymbol = fiat ? fiat.string : tokenSymbol;
const tokenIcon = useGetIcon(formattedTokenType);
const tokenIcon = useGetIcon(assetIcon);

return (
<Button
Expand All @@ -39,9 +37,9 @@ export function PoolListItem<T extends InputTokenType | OutputTokenType>({
</span>
<span className="flex flex-col">
<span className="text-lg leading-5 dark:text-white">
<strong>{formattedTokenSymbol}</strong>
<strong>{tokenSymbol}</strong>
</span>
<span className="text-sm leading-5 text-neutral-500">{formattedTokenSymbol}</span>
<span className="text-sm leading-5 text-neutral-500">{tokenSymbol}</span>
</span>
</Button>
);
Expand Down
11 changes: 6 additions & 5 deletions src/components/InputKeys/SelectionModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Fiat, InputTokenType, OutputTokenType } from '../../constants/tokenConf
import { Dialog } from '../Dialog';
import { Skeleton } from '../Skeleton';
import { PoolListItem } from './PoolListItem';
import { AssetIconType } from '../../hooks/useGetIcon';

interface PoolSelectorModalProps<T extends InputTokenType | OutputTokenType> extends PoolListProps<T> {
isLoading?: boolean;
Expand All @@ -12,9 +13,9 @@ interface PoolSelectorModalProps<T extends InputTokenType | OutputTokenType> ext
}

interface PoolListProps<T extends InputTokenType | OutputTokenType> {
definitions: { assetSymbol: string; type: T; fiat?: Fiat }[];
definitions: { assetSymbol: string; type: T; assetIcon: AssetIconType }[];
onSelect: (tokenType: InputTokenType | OutputTokenType) => void;
selected: InputTokenType | OutputTokenType | undefined;
selected: InputTokenType | OutputTokenType;
}

export function PoolSelectorModal<T extends InputTokenType | OutputTokenType>({
Expand Down Expand Up @@ -45,14 +46,14 @@ function PoolList<T extends InputTokenType | OutputTokenType>({ onSelect, defini
placeholder="Find by name or address"
/>
<div className="flex flex-col gap-1">
{definitions.map(({ fiat, assetSymbol, type }) => (
{definitions.map(({ assetIcon, assetSymbol, type }) => (
<PoolListItem
key={type}
isSelected={selected === assetSymbol}
isSelected={selected === type}
onSelect={onSelect}
tokenType={type}
fiat={fiat}
tokenSymbol={assetSymbol}
assetIcon={assetIcon}
/>
))}
</div>
Expand Down
15 changes: 7 additions & 8 deletions src/components/buttons/AssetButton/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { InputTokenType, OutputTokenType } from '../../../constants/tokenConfig';
import { useGetIcon } from '../../../hooks/useGetIcon';
import { AssetIconType, useGetIcon } from '../../../hooks/useGetIcon';

interface AssetButtonProps {
tokenType?: InputTokenType | OutputTokenType | 'eur';
tokenSymbol?: string;
assetIcon: AssetIconType;
tokenSymbol: string;
onClick: () => void;
}
export function AssetButton({ tokenType, tokenSymbol, onClick }: AssetButtonProps) {
const icon = useGetIcon(tokenType);
export function AssetButton({ assetIcon, tokenSymbol, onClick }: AssetButtonProps) {
const icon = useGetIcon(assetIcon);

return (
<button
Expand All @@ -16,9 +15,9 @@ export function AssetButton({ tokenType, tokenSymbol, onClick }: AssetButtonProp
type="button"
>
<span className="h-full p-px mr-1 rounded-full">
{tokenType && <img src={icon} alt={tokenType} className="w-auto h-full" />}
<img src={icon} alt={assetIcon} className="w-auto h-full" />
</span>
<strong className="font-bold text-black">{tokenSymbol || 'Select'}</strong>
<strong className="font-bold text-black">{tokenSymbol}</strong>
</button>
);
}
15 changes: 10 additions & 5 deletions src/constants/tokenConfig.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { AssetIconType } from '../hooks/useGetIcon';

export interface InputTokenDetails {
assetSymbol: string;
erc20AddressSourceChain: `0x${string}`;
Expand All @@ -6,20 +8,21 @@ export interface InputTokenDetails {
pendulumCurrencyId: { XCM: number };
pendulumAssetSymbol: string;
};
polygonAssetIcon: AssetIconType;
decimals: number;
}

export type InputTokenType = 'usdc' | 'usdce';

export interface Fiat {
symbol: 'eur';
string: 'EUR';
assetIcon: AssetIconType;
symbol: string;
}

export interface OutputTokenDetails {
tomlFileUrl: string;
decimals: number;
fiat?: Fiat;
fiat: Fiat;
stellarAsset: {
code: {
hex: string;
Expand All @@ -44,6 +47,7 @@ export const INPUT_TOKEN_CONFIG: Record<InputTokenType, InputTokenDetails> = {
pendulumCurrencyId: { XCM: 12 },
pendulumAssetSymbol: 'USDC.axl',
},
polygonAssetIcon: 'polygonUSDC',
decimals: 6,
},
usdce: {
Expand All @@ -54,6 +58,7 @@ export const INPUT_TOKEN_CONFIG: Record<InputTokenType, InputTokenDetails> = {
pendulumCurrencyId: { XCM: 12 },
pendulumAssetSymbol: 'USDC.axl',
},
polygonAssetIcon: 'polygonUSDC',
decimals: 6,
},
};
Expand All @@ -64,8 +69,8 @@ export const OUTPUT_TOKEN_CONFIG: Record<OutputTokenType, OutputTokenDetails> =
tomlFileUrl: 'https://mykobo.co/.well-known/stellar.toml',
decimals: 12,
fiat: {
symbol: 'eur',
string: 'EUR',
assetIcon: 'eur',
symbol: 'EUR',
},
stellarAsset: {
code: {
Expand Down
28 changes: 7 additions & 21 deletions src/hooks/useGetIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,18 @@
import { useAccount, useChainId } from 'wagmi';
import { polygon } from 'wagmi/chains';

import EURC from '../assets/coins/EURC.png';
import EUR from '../assets/coins/EUR.svg';
import USDC from '../assets/coins/USDC.png';
import USDC_POLYGON from '../assets/coins/USDC_POLYGON.svg';
import DefaultIcon from '../assets/coins/PEN.png';

const ICONS = {
default: {
eurc: EURC,
eur: EUR,
usdc: USDC,
usdce: USDC,
},
[polygon.id]: {
usdc: USDC_POLYGON,
usdce: USDC_POLYGON,
},
eurc: EURC,
eur: EUR,
usdc: USDC,
polygonUSDC: USDC_POLYGON,
};

type TokenType = keyof typeof ICONS.default | keyof (typeof ICONS)[typeof polygon.id];

export function useGetIcon(token?: TokenType, defaultIcon = DefaultIcon) {
const chainId = useChainId();
const { isConnected } = useAccount();

const iconMap = isConnected ? ICONS[chainId as keyof typeof ICONS] : ICONS.default;
export type AssetIconType = keyof typeof ICONS;

return token ? iconMap[token as keyof typeof iconMap] || ICONS.default[token] || defaultIcon : defaultIcon;
export function useGetIcon(assetIcon: AssetIconType, defaultIcon = DefaultIcon) {
return ICONS[assetIcon];
}
Loading

0 comments on commit b82a70f

Please sign in to comment.