Skip to content

Commit

Permalink
feat(wallet): rebrand home - update coin (#1718)
Browse files Browse the repository at this point in the history
* feat: add card compoentn

* feat: use constants

* feat: update CoinItem component

* feat: refine icon

* fix build

* feat: update icon and images styles

* refactor: update iota-sdk name

* feat: bring back pinned coins

* feat: add clickableAction prop

* feat: remove iconSize prop

* feat: pass pinned coins to useSortedCoinsByCategories hook

* feat: add svg

* feat: update icons

* feat: minor improvements

---------

Co-authored-by: Begoña Alvarez <[email protected]>
  • Loading branch information
evavirseda and begonaalvarezd authored Aug 14, 2024
1 parent c8f8e03 commit b571920
Show file tree
Hide file tree
Showing 23 changed files with 141 additions and 182 deletions.
18 changes: 8 additions & 10 deletions apps/core/src/hooks/useSortedCoinsByCategories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,20 @@ function sortCoins(balances: CoinBalance[]) {
});
}

export function useSortedCoinsByCategories(coinBalances: CoinBalance[]) {
export function useSortedCoinsByCategories(
coinBalances: CoinBalance[],
pinnedCoinTypes?: string[],
) {
const recognizedPackages = DEFAULT_RECOGNIZED_PACKAGES; // previous: useRecognizedPackages();

// Commented out pinnedCoinTypes until https://github.com/iotaledger/iota/issues/832 is resolved
// const [pinnedCoinTypes] = usePinnedCoinTypes();

return useMemo(() => {
const reducedCoinBalances = coinBalances?.reduce(
(acc, coinBalance) => {
if (recognizedPackages.includes(coinBalance.coinType.split('::')[0])) {
acc.recognized.push(coinBalance);
}
// else if (pinnedCoinTypes.includes(coinBalance.coinType)) {
// acc.pinned.push(coinBalance);
// }
else {
} else if (pinnedCoinTypes?.includes(coinBalance.coinType)) {
acc.pinned.push(coinBalance);
} else {
acc.unrecognized.push(coinBalance);
}
return acc;
Expand All @@ -49,5 +47,5 @@ export function useSortedCoinsByCategories(coinBalances: CoinBalance[]) {
pinned: sortCoins(reducedCoinBalances.pinned),
unrecognized: sortCoins(reducedCoinBalances.unrecognized),
};
}, [coinBalances, recognizedPackages /*pinnedCoinTypes*/]);
}, [coinBalances, recognizedPackages, pinnedCoinTypes]);
}
18 changes: 18 additions & 0 deletions apps/ui-icons/src/Pined.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { SVGProps } from 'react';
export default function SvgPined(props: SVGProps<SVGSVGElement>) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
fill="none"
viewBox="0 0 24 24"
{...props}
>
<path fill="currentColor" d="m16 12 2 2v2h-5v6l-1 1-1-1v-6H6v-2l2-2V5H7V3h10v2h-1z" />
</svg>
);
}
21 changes: 21 additions & 0 deletions apps/ui-icons/src/Unpined.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { SVGProps } from 'react';
export default function SvgUnpined(props: SVGProps<SVGSVGElement>) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
fill="none"
viewBox="0 0 24 24"
{...props}
>
<path
fill="currentColor"
d="M17 3v2h-1v8.175L7.825 5 7 4.175V3zm-5 20-1-1v-6H6v-2l2-2v-1.15L1.4 4.2l1.4-1.4 18.4 18.4-1.45 1.4-6.6-6.6H13v6z"
/>
</svg>
);
}
2 changes: 2 additions & 0 deletions apps/ui-icons/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export { default as MoreHoriz } from './MoreHoriz';
export { default as MoreVert } from './MoreVert';
export { default as OutboundLink } from './OutboundLink';
export { default as Person } from './Person';
export { default as Pined } from './Pined';
export { default as PlaceholderReplace } from './PlaceholderReplace';
export { default as QrCode } from './QrCode';
export { default as RadioOff } from './RadioOff';
Expand All @@ -68,6 +69,7 @@ export { default as SwapAccount } from './SwapAccount';
export { default as ThumbUp } from './ThumbUp';
export { default as TriangleDown } from './TriangleDown';
export { default as TriangleUp } from './TriangleUp';
export { default as Unpined } from './Unpined';
export { default as Vest } from './Vest';
export { default as VisibilityOff } from './VisibilityOff';
export { default as VisibilityOn } from './VisibilityOn';
3 changes: 3 additions & 0 deletions apps/ui-icons/svgs/pined.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions apps/ui-icons/svgs/unpined.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 12 additions & 3 deletions apps/ui-kit/src/lib/components/molecules/card/CardBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,22 @@
export type CardBodyProps = {
title: string;
subtitle?: string;
clickableAction?: React.ReactNode;
};

export function CardBody({ title, subtitle }: CardBodyProps) {
export function CardBody({ title, subtitle, clickableAction }: CardBodyProps) {
const handleActionCardBodyClick = (event: React.MouseEvent) => {
event?.stopPropagation();
};
return (
<div className="flex w-full flex-col">
<div className="font-inter text-title-md text-neutral-10 dark:text-neutral-92">
{title}
<div className="flex flex-row gap-x-xs">
<div className="font-inter text-title-md text-neutral-10 dark:text-neutral-92">
{title}
</div>
{clickableAction && (
<div onClick={handleActionCardBodyClick}>{clickableAction}</div>
)}
</div>
{subtitle && (
<div className="font-inter text-body-md text-neutral-40 dark:text-neutral-60">
Expand Down
85 changes: 29 additions & 56 deletions apps/wallet/src/ui/app/components/active-coins-card/CoinItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,75 +2,48 @@
// Modifications Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { Text } from '_app/shared/text';
import { CoinIcon } from '_components/coin-icon';
import { useFormatCoin } from '@iota/core';
import { type ReactNode } from 'react';
import {
Card,
CardAction,
CardActionType,
CardBody,
CardImage,
CardType,
ImageType,
} from '@iota/apps-ui-kit';
import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils';

interface CoinItemProps {
coinType: string;
balance: bigint;
isActive?: boolean;
usd?: number;
centerAction?: ReactNode;
subtitle?: string;
clickableAction?: ReactNode;
}

export function CoinItem({
coinType,
balance,
isActive,
usd,
centerAction,
subtitle,
}: CoinItemProps) {
export function CoinItem({ coinType, balance, usd, clickableAction }: CoinItemProps) {
const [formatted, symbol, { data: coinMeta }] = useFormatCoin(balance, coinType);
const isIota = coinType === IOTA_TYPE_ARG;

return (
<div className="hover:bg-iota/10 flex w-full items-center justify-center gap-2.5 rounded py-3 pl-1.5 pr-2">
<CoinIcon coinType={coinType} size={isActive ? 'sm' : 'md'} />
<div className="flex flex-1 items-center justify-between gap-1.5">
<div className="max-w-token-width">
<Text variant="body" color="gray-90" weight="semibold" truncate>
{coinMeta?.name || symbol} {isActive ? 'available' : ''}
</Text>
{!isActive && !subtitle ? (
<div className="mt-1.5">
<Text variant="subtitle" color="steel-dark" weight="medium">
{symbol}
</Text>
</div>
) : null}
{subtitle ? (
<div className="mt-1.5">
<Text variant="subtitle" color="steel" weight="medium">
{subtitle}
</Text>
</div>
) : null}
<Card type={CardType.Default}>
<CardImage type={ImageType.BgTransparent}>
<div className="flex h-10 w-10 items-center justify-center rounded-full border border-shader-neutral-light-8 text-neutral-10">
<CoinIcon coinType={coinType} />
</div>

{centerAction}

<div className="flex flex-row items-center justify-center">
{isActive ? (
<Text variant="body" color="steel-darker" weight="medium">
{formatted}
</Text>
) : (
<div data-testid={coinType} className="max-w-token-width">
<Text variant="body" color="gray-90" weight="medium" truncate>
{formatted} {symbol}
</Text>
{usd && (
<Text variant="caption" color="steel-dark" weight="medium">
${usd.toLocaleString('en-US')}
</Text>
)}
</div>
)}
</div>
</div>
</div>
</CardImage>
<CardBody
title={isIota ? (coinMeta?.name || '').toUpperCase() : coinMeta?.name || symbol}
subtitle={symbol}
clickableAction={clickableAction}
/>
<CardAction
type={CardActionType.SupportingText}
title={`${formatted} ${symbol}`}
subtitle={usd?.toLocaleString('en-US')}
/>
</Card>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ export function ActiveCoinsCard({
<CoinItem
coinType={activeCoin.coinType}
balance={BigInt(activeCoin.totalBalance)}
isActive
/>
</Link>
)
Expand Down
57 changes: 14 additions & 43 deletions apps/wallet/src/ui/app/components/coin-icon/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,8 @@

import { ImageIcon } from '_app/shared/image-icon';
import { useCoinMetadata } from '@iota/core';
import { Iota, Unstaked } from '@iota/icons';
import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils';
import { cva, type VariantProps } from 'class-variance-authority';

const imageStyle = cva(['rounded-full flex'], {
variants: {
size: {
sm: 'w-6 h-6',
md: 'w-7.5 h-7.5',
lg: 'md:w-10 md:h-10 w-8 h-8',
xl: 'md:w-31.5 md:h-31.5 w-16 h-16 ',
},
fill: {
iota: 'bg-iota',
iotaPrimary2023: 'bg-iota-primaryBlue2023',
},
},
defaultVariants: {
size: 'md',
fill: 'iotaPrimary2023',
},
});

function IotaCoin() {
return (
<Iota className="flex h-full w-full items-center justify-center rounded-full p-1.5 text-body text-white" />
);
}
import { IotaLogoMark } from '@iota/ui-icons';

interface NonIotaCoinProps {
coinType: string;
Expand All @@ -40,29 +14,26 @@ interface NonIotaCoinProps {
function NonIotaCoin({ coinType }: NonIotaCoinProps) {
const { data: coinMeta } = useCoinMetadata(coinType);
return (
<div className="bg-steel flex h-full w-full items-center justify-center rounded-full text-white">
{coinMeta?.iconUrl ? (
<ImageIcon
src={coinMeta.iconUrl}
label={coinMeta.name || coinType}
fallback={coinMeta.name || coinType}
rounded="full"
/>
) : (
<Unstaked />
)}
<div className="flex h-full w-full items-center justify-center rounded-full">
<ImageIcon
src={coinMeta?.iconUrl}
label={coinMeta?.name || coinType}
fallback={coinMeta?.name || coinType}
/>
</div>
);
}

export interface CoinIconProps extends VariantProps<typeof imageStyle> {
export interface CoinIconProps {
coinType: string;
}

export function CoinIcon({ coinType, ...styleProps }: CoinIconProps) {
return (
<div className={imageStyle(styleProps)}>
{coinType === IOTA_TYPE_ARG ? <IotaCoin /> : <NonIotaCoin coinType={coinType} />}
export function CoinIcon({ coinType }: CoinIconProps) {
return coinType === IOTA_TYPE_ARG ? (
<div className="h-full w-full p-1">
<IotaLogoMark className="h-full w-full" />
</div>
) : (
<NonIotaCoin coinType={coinType} />
);
}
4 changes: 2 additions & 2 deletions apps/wallet/src/ui/app/components/iota-apps/IotaApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ function CardView({ name, link, icon }: CardViewProps) {
return (
<div className="border-gray-45 hover:border-iota/30 hover:bg-iota/10 box-border flex h-32 w-full flex-col rounded-2xl border border-solid bg-white p-3.75">
<div className="mb-1 flex">
<ImageIcon src={icon || null} label={name} fallback={name} size="lg" rounded="lg" />
<ImageIcon src={icon || null} label={name} fallback={name} />
</div>

<div className="item-start flex flex-col justify-start gap-1">
Expand All @@ -59,7 +59,7 @@ interface ListViewProps {
function ListView({ name, icon, description, tags }: ListViewProps) {
return (
<div className="item-center hover:bg-iota/10 box-border flex gap-3 rounded bg-white px-1.25 py-3.5">
<ImageIcon src={icon || null} label={name} fallback={name} size="xxl" rounded="lg" />
<ImageIcon src={icon || null} label={name} fallback={name} />
<div className="flex flex-col justify-center gap-1">
<Text variant="body" weight="semibold" color="iota-dark">
{name}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ export function StakeTxnCard({ event }: StakeTxnCardProps) {
<ValidatorLogo
validatorAddress={validatorAddress}
showAddress
iconSize="md"
size="body"
activeEpoch={json?.epoch}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ export function UnStakeTxnCard({ event }: UnStakeTxnCardProps) {
<ValidatorLogo
validatorAddress={validatorAddress}
showAddress
iconSize="md"
size="body"
/>
</div>
Expand Down
8 changes: 3 additions & 5 deletions apps/wallet/src/ui/app/pages/home/tokens/TokenLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@ import { Link } from 'react-router-dom';

type TokenLinkProps = {
coinBalance: CoinBalance;
centerAction?: ReactNode;
subtitle?: string;
clickableAction?: ReactNode;
};

export function TokenLink({ coinBalance, centerAction, subtitle }: TokenLinkProps) {
export function TokenLink({ coinBalance, clickableAction }: TokenLinkProps) {
return (
<Link
to={`/send?type=${encodeURIComponent(coinBalance.coinType)}`}
Expand All @@ -31,8 +30,7 @@ export function TokenLink({ coinBalance, centerAction, subtitle }: TokenLinkProp
<CoinItem
coinType={coinBalance.coinType}
balance={BigInt(coinBalance.totalBalance)}
centerAction={centerAction}
subtitle={subtitle}
clickableAction={clickableAction}
/>
</Link>
);
Expand Down
Loading

0 comments on commit b571920

Please sign in to comment.