diff --git a/packages/widget/src/components/atoms/image/index.tsx b/packages/widget/src/components/atoms/image/index.tsx index 9e9e018b..b8c9a79e 100644 --- a/packages/widget/src/components/atoms/image/index.tsx +++ b/packages/widget/src/components/atoms/image/index.tsx @@ -1,6 +1,5 @@ import type { HTMLProps } from "react"; import { useMemo } from "react"; -import { getBackgroundColor } from "../../../utils"; import type { BoxProps } from "../box"; import { Box } from "../box"; @@ -53,9 +52,8 @@ const createMonogramImageSrc = (name?: string) => { if (!firstCharacter) return undefined; const initial = escapeForSvg(firstCharacter.toUpperCase()); - const backgroundColor = getBackgroundColor(name); - const svg = `${initial}`; + const svg = `${initial}`; return `data:image/svg+xml;charset=UTF-8,${encodeURIComponent(svg)}`; }; diff --git a/packages/widget/src/components/atoms/token-icon/index.tsx b/packages/widget/src/components/atoms/token-icon/index.tsx index 1c14f4bb..acc183a5 100644 --- a/packages/widget/src/components/atoms/token-icon/index.tsx +++ b/packages/widget/src/components/atoms/token-icon/index.tsx @@ -38,6 +38,7 @@ export const TokenIcon = ({ {!hideNetwork && !hideNetworkLogo && ( )} diff --git a/packages/widget/src/components/atoms/token-icon/network-icon-image/index.tsx b/packages/widget/src/components/atoms/token-icon/network-icon-image/index.tsx index c604dcc0..3f4946bf 100644 --- a/packages/widget/src/components/atoms/token-icon/network-icon-image/index.tsx +++ b/packages/widget/src/components/atoms/token-icon/network-icon-image/index.tsx @@ -5,16 +5,19 @@ import { logoContainer, logoImage } from "./style.css"; type NetworkLogoImageProps = { networkLogoUri: string; + networkName?: string; tokenNetworkLogoHw?: Atoms["hw"]; }; export const NetworkLogoImage = ({ networkLogoUri, + networkName, tokenNetworkLogoHw = "3", }: NetworkLogoImageProps) => ( diff --git a/packages/widget/src/components/atoms/token-icon/network-icon-image/style.css.ts b/packages/widget/src/components/atoms/token-icon/network-icon-image/style.css.ts index 7e2fe1cb..0b097e61 100644 --- a/packages/widget/src/components/atoms/token-icon/network-icon-image/style.css.ts +++ b/packages/widget/src/components/atoms/token-icon/network-icon-image/style.css.ts @@ -1,17 +1,24 @@ import { style } from "@vanilla-extract/css"; -export const logoContainer = style({ +const baseContainer = style({ position: "absolute", bottom: -2, right: -2, borderRadius: "50%", - padding: "4px", - backgroundColor: "rgba(37,37,37, 0.95)", + padding: "3px", display: "flex", alignItems: "center", justifyContent: "center", }); +export const logoContainer = style([ + baseContainer, + { + backgroundColor: "#ffffff", + boxShadow: "0 0 0 1px rgba(0, 0, 0, 0.06)", + }, +]); + export const logoImage = style({ maxWidth: "100%", height: "auto", diff --git a/packages/widget/src/components/atoms/token-icon/provider-icon/index.tsx b/packages/widget/src/components/atoms/token-icon/provider-icon/index.tsx index 4ad88d01..19dcd2aa 100644 --- a/packages/widget/src/components/atoms/token-icon/provider-icon/index.tsx +++ b/packages/widget/src/components/atoms/token-icon/provider-icon/index.tsx @@ -38,6 +38,7 @@ export const ProviderIcon = ({ {!hideNetwork && !hideNetworkLogo && ( )} diff --git a/packages/widget/src/components/molecules/reward-token-details/index.tsx b/packages/widget/src/components/molecules/reward-token-details/index.tsx index 183aad2f..e4e1b333 100644 --- a/packages/widget/src/components/molecules/reward-token-details/index.tsx +++ b/packages/widget/src/components/molecules/reward-token-details/index.tsx @@ -3,6 +3,7 @@ import type { ComponentProps } from "react"; import { Trans } from "react-i18next"; import type { YieldPendingActionType } from "../../../domain/types/pending-action"; import type { useRewardTokenDetails } from "../../../hooks/use-reward-token-details"; +import { humanizePendingActionType } from "../../../utils/formatters"; import { Box } from "../../atoms/box"; import { MorphoStarsIcon } from "../../atoms/icons/morpho-stars"; import { Image } from "../../atoms/image"; @@ -35,6 +36,11 @@ export const RewardTokenDetails = ({ return "unstake_review.unstake_from"; })(); + const i18nDefaults = + rest.type === "pendingAction" + ? humanizePendingActionType(rest.pendingAction) + : undefined; + return rewardToken .map((rt) => { return ( @@ -66,6 +72,7 @@ export const RewardTokenDetails = ({ { label={t( `position_details.pending_action_button.${ val.pendingActionDto.type.toLowerCase() as Lowercase - }` + }`, + { + defaultValue: humanizePendingActionType( + val.pendingActionDto.type + ), + } )} onMaxClick={null} formattedAmount={val.formattedAmount} diff --git a/packages/widget/src/pages-dashboard/position-details/position-details-model.tsx b/packages/widget/src/pages-dashboard/position-details/position-details-model.tsx index b8c37533..1a35b55c 100644 --- a/packages/widget/src/pages-dashboard/position-details/position-details-model.tsx +++ b/packages/widget/src/pages-dashboard/position-details/position-details-model.tsx @@ -419,13 +419,7 @@ const getStatusSummary = ({ pendingAction.pendingActionDto.type === "CLAIM_REWARDS" ? "claim" : "action", - value: t( - `position_details.pending_action.${ - pendingAction.pendingActionDto.type.toLowerCase() as Lowercase< - YieldPendingActionDto["type"] - > - }` - ), + value: formatPendingActionLabel(pendingAction.pendingActionDto.type, t), }; } @@ -635,6 +629,17 @@ const balanceTypePriority: YieldBalanceType[] = [ const formatBalanceTypeLabel = (type: YieldBalanceType, t: TFunction) => t(`position_details.balance_type.${type}`); +// Pending action types come from the API and can outpace our translation map +// (e.g. RWA-specific actions). Fall back to a humanized version of the type so +// the card never renders a raw translation key. +const formatPendingActionLabel = ( + type: YieldPendingActionDto["type"], + t: TFunction +) => + t(`position_details.pending_action.${type.toLowerCase()}`, { + defaultValue: formatEnumValue(type), + }); + const formatUsdSubValue = ( value: string | number | BigNumber | null | undefined ) => { diff --git a/packages/widget/src/pages/position-details/components/static-action-block.tsx b/packages/widget/src/pages/position-details/components/static-action-block.tsx index 0aa39069..50473c80 100644 --- a/packages/widget/src/pages/position-details/components/static-action-block.tsx +++ b/packages/widget/src/pages/position-details/components/static-action-block.tsx @@ -10,6 +10,7 @@ import type { import type { YieldBalanceDto } from "../../../domain/types/positions"; import { isEthenaUsdeStaking, type Yield } from "../../../domain/types/yields"; import { defaultFormattedNumber } from "../../../utils"; +import { humanizePendingActionType } from "../../../utils/formatters"; import type { usePositionDetails } from "../hooks/use-position-details"; type StaticActionBlockProps = { @@ -60,6 +61,9 @@ export const StaticActionBlock = ({ context: isEthenaUsdeStaking(yieldId) ? "ethena_usde" : undefined, + defaultValue: humanizePendingActionType( + pendingActionDto.type + ), } ), }} @@ -93,7 +97,10 @@ export const StaticActionBlock = ({ {t( `position_details.pending_action_button.${ pendingActionDto.type.toLowerCase() as Lowercase - }` + }`, + { + defaultValue: humanizePendingActionType(pendingActionDto.type), + } )} diff --git a/packages/widget/src/utils/formatters.ts b/packages/widget/src/utils/formatters.ts index a806e4ed..f36880c2 100644 --- a/packages/widget/src/utils/formatters.ts +++ b/packages/widget/src/utils/formatters.ts @@ -136,6 +136,16 @@ export const formatCompactUsd = (value: string | number | null | undefined) => { return `$${compactUsdFormatter.format(amount.toNumber())}`; }; +// Pending action types come straight from the API and can outpace our +// translation maps (e.g. RWA-specific actions like WITHDRAWAL_REQUEST). Use this +// as the i18n `defaultValue`/`defaults` so we never render a raw translation key. +export const humanizePendingActionType = (type: string): string => + type + .split("_") + .filter(Boolean) + .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) + .join(" "); + export const capitalizeFirstLetters = (text: string): string => Maybe.fromNullable(text) .map((t) => diff --git a/packages/widget/src/utils/index.ts b/packages/widget/src/utils/index.ts index 908203d7..20232712 100644 --- a/packages/widget/src/utils/index.ts +++ b/packages/widget/src/utils/index.ts @@ -43,13 +43,13 @@ export const defaultFormattedNumber = (number: string | BigNumber | number) => export const APToPercentage = (ap: number) => formatNumber((ap * 100).toFixed(2)); -const colorsTuple = ["#6B69D6", "#F1C40F", "#1ABC9C", "#E74C3C"]; +// const colorsTuple = ["#6B69D6", "#F1C40F", "#1ABC9C", "#E74C3C"]; -export const getBackgroundColor = (stringInput: string) => { - const char = stringInput.charCodeAt(0); +// export const getBackgroundColor = (stringInput: string) => { +// const char = stringInput.charCodeAt(0); - return colorsTuple[char % colorsTuple.length] ?? colorsTuple[0]; -}; +// return colorsTuple[char % colorsTuple.length] ?? colorsTuple[0]; +// }; export const isIframe = () => MaybeWindow.map((w) => w.parent !== w).orDefault(false);