Skip to content

Commit

Permalink
fix: resolve conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
brancoder committed Apr 22, 2024
2 parents 77bf752 + a0bd434 commit b0f9ed0
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 47 deletions.
37 changes: 20 additions & 17 deletions client/src/app/components/CardInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,38 @@
import React from "react";
import CopyButton from "~app/components/CopyButton";
import Tooltip from "~app/components/Tooltip";
import classNames from "classnames";

import "./CardInfo.scss";

export interface CardInfoDetail {
title: string;
value?: number | string | null;
onClickValue?: () => void;
showCopyBtn?: boolean;
copyValue?: string;
}

export interface CardInfoProps {
interface CardInfoProps {
/**
* The title of the card.
*/
title: string;
tooltip?: string;
value?: number | string | null;
onClickValue?: () => void;
showCopyBtn?: boolean;
copyValue?: string;
details?: (CardInfoDetail | null)[];
options?: {
headerDirectionRow?: boolean;
};
}

export const CardInfo = ({ details, tooltip, title, value, onClickValue = () => {}, showCopyBtn }: CardInfoProps) => {
export const CardInfo = ({ options, details, tooltip, title, value, onClickValue = () => {}, copyValue }: CardInfoProps) => {
const detailsFiltered = (details?.filter((i) => i !== null) as CardInfoDetail[]) || [];

return (
<div className="card-info">
<div className="card-info--header">
<div className={classNames("card-info--header", { "row middle space-between": !!options?.headerDirectionRow })}>
<div className="card-info--header-title">
<div className="card-info__title">{title}</div>
{!!tooltip && (
Expand All @@ -38,16 +43,14 @@ export const CardInfo = ({ details, tooltip, title, value, onClickValue = () =>
</div>
)}
</div>
{!!value && (
<div className="card-info__value-wrap" onClick={onClickValue}>
<div className="card-info__value">{value}</div>
{isValueNotZero(value) && showCopyBtn && (
<div className="card-info__copy">
<CopyButton copy={String(value)} />
</div>
)}
</div>
)}
<div className="card-info__value-wrap" onClick={onClickValue}>
<div className="card-info__value">{value}</div>
{isValueNotZero(value) && !!copyValue && (
<div className="card-info__copy">
<CopyButton copy={String(copyValue)} />
</div>
)}
</div>
</div>
{!!detailsFiltered.length && (
<div className="card-info__details">
Expand All @@ -57,9 +60,9 @@ export const CardInfo = ({ details, tooltip, title, value, onClickValue = () =>
<div className="card-info__detail-title">{detail.title}</div>
<div className="card-info__detail-value" onClick={detail.onClickValue}>
{detail.value !== null ? detail.value : "-"}
{isValueNotZero(detail.value) && detail.showCopyBtn && (
{isValueNotZero(detail.value) && !!detail.copyValue && (
<div className="card-info__copy">
<CopyButton copy={String(detail.value)} />
<CopyButton copy={String(detail.copyValue)} />
</div>
)}
</div>
Expand Down
2 changes: 1 addition & 1 deletion client/src/app/components/nova/address/AddressBalance.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@import "../../../../scss/media-queries";

.balance-wrapper {
.balance-wrapper.nova {
display: flex;
flex-direction: column;
gap: 24px;
Expand Down
140 changes: 111 additions & 29 deletions client/src/app/components/nova/address/AddressBalance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { IManaBalance } from "~/models/api/nova/address/IAddressBalanceResponse"
import { formatAmount } from "~helpers/stardust/valueFormatHelper";
import "./AddressBalance.scss";
import { CardInfo, CardInfoDetail } from "~app/components/CardInfo";
import { NumberHelper } from "~helpers/numberHelper";

interface AddressBalanceProps {
/**
Expand Down Expand Up @@ -36,6 +37,21 @@ interface AddressBalanceProps {
readonly storageDeposit?: number | null;
}

type FormatField =
| "baseTokenBalance"
| "conditionalBaseTokenBalance"
| "storageDeposit"
| "availableManaBalance"
| "availableStoredMana"
| "availableDecayMana"
| "availablePotentialMana"
| "blockIssuanceCredits"
| "manaRewards"
| "conditionallyLockedMana"
| "conditionalStoredMana"
| "conditionalDecayMana"
| "conditionalPotentialMana";

const CONDITIONAL_BALANCE_INFO =
"These funds reside within outputs with additional unlock conditions which might be potentially un-lockable";

Expand All @@ -49,10 +65,23 @@ const AddressBalance: React.FC<AddressBalanceProps> = ({
storageDeposit,
}) => {
const { tokenInfo, manaInfo } = useNetworkInfoNova((s) => s.networkInfo);
const [formatBaseTokenBalanceFull, setFormatBaseTokenBalanceFull] = useState(false);
const [formatManaBalanceFull, setFormatManaBalanceFull] = useState(false);
const [formatConditionalBalanceFull, setFormatConditionalBalanceFull] = useState(false);
const [formatStorageBalanceFull, setFormatStorageBalanceFull] = useState(false);
const [isFormat, setIsFormat] = useState<{ [k in FormatField]: boolean }>({
baseTokenBalance: false,
conditionalBaseTokenBalance: false,
storageDeposit: false,

availableManaBalance: false,
availableStoredMana: false,
availableDecayMana: false,
availablePotentialMana: false,
blockIssuanceCredits: false,
manaRewards: false,

conditionallyLockedMana: false,
conditionalStoredMana: false,
conditionalDecayMana: false,
conditionalPotentialMana: false,
});

if (totalBaseTokenBalance === null) {
return null;
Expand All @@ -75,72 +104,125 @@ const AddressBalance: React.FC<AddressBalanceProps> = ({
availablePotentialMana === null || totalPotentialMana === null ? null : totalPotentialMana - availablePotentialMana;

const availableBaseTokenAmount = (() => {
const balance = shouldShowExtendedBalance ? availableBaseTokenBalance : totalBaseTokenBalance;
return balance && balance > 0 ? formatAmount(balance, tokenInfo, formatBaseTokenBalanceFull) : 0;
const balance = (shouldShowExtendedBalance ? availableBaseTokenBalance : totalBaseTokenBalance) || 0;
return {
formatted: formatAmount(balance, tokenInfo, isFormat.baseTokenBalance),
full: balance,
};
})();

const manaFactory = (
mana: bigint | number | null | undefined,
title: string,
isFormat: boolean,
setFormat: React.Dispatch<React.SetStateAction<boolean>>,
toggleFormat: () => void,
): CardInfoDetail | null => {
if (mana !== null && mana !== undefined && mana > 0) {
if (mana !== null && mana !== undefined) {
return {
title: title,
value: formatAmount(mana, manaInfo, isFormat),
onClickValue: () => setFormat(!isFormat),
showCopyBtn: true,
onClickValue: toggleFormat,
copyValue: String(mana),
};
}

return null;
return {
title: title,
value: formatAmount(0, manaInfo, isFormat),
onClickValue: toggleFormat,
copyValue: "0",
};
};

const availableManaSum = NumberHelper.sumValues(
availableStoredMana,
availableDecayMana,
availablePotentialMana,
blockIssuanceCredits,
manaRewards,
);
const conditionallyLockedManaSum = NumberHelper.sumValues(conditionalStoredMana, conditionalDecayMana, conditionalPotentialMana);

const toggleFormat = (field: FormatField) => () => {
setIsFormat((prev) => ({ ...prev, [field]: !prev[field] }));
};

return (
<div className="balance-wrapper">
<div className="balance-wrapper nova">
<div className="balance-wrapper--row">
<CardInfo
title="Available Base Token"
value={availableBaseTokenAmount}
onClickValue={() => setFormatBaseTokenBalanceFull(!formatBaseTokenBalanceFull)}
showCopyBtn
value={availableBaseTokenAmount.formatted}
onClickValue={toggleFormat("baseTokenBalance")}
copyValue={String(availableBaseTokenAmount.full)}
/>
{shouldShowExtendedBalance && (
<CardInfo
title="Conditionally Locked Base Token"
value={formatAmount(conditionalBaseTokenBalance, tokenInfo, formatConditionalBalanceFull)}
onClickValue={() => setFormatConditionalBalanceFull(!formatConditionalBalanceFull)}
value={formatAmount(conditionalBaseTokenBalance, tokenInfo, isFormat.conditionalBaseTokenBalance)}
onClickValue={toggleFormat("conditionalBaseTokenBalance")}
tooltip={CONDITIONAL_BALANCE_INFO}
showCopyBtn
copyValue={String(conditionalBaseTokenBalance)}
/>
)}

<CardInfo
title="Storage Deposit"
value={storageDeposit ? formatAmount(storageDeposit, tokenInfo, formatStorageBalanceFull) : 0}
onClickValue={() => setFormatStorageBalanceFull(!formatStorageBalanceFull)}
showCopyBtn
value={formatAmount(storageDeposit || 0, tokenInfo, isFormat.storageDeposit)}
onClickValue={toggleFormat("storageDeposit")}
copyValue={String(storageDeposit || 0)}
/>
</div>
<div className="balance-wrapper--row">
<CardInfo
title="Available Mana"
value={formatAmount(availableManaSum, manaInfo, isFormat.availableManaBalance)}
onClickValue={toggleFormat("availableManaBalance")}
copyValue={String(availableManaSum)}
options={{ headerDirectionRow: true }}
details={[
manaFactory(availableStoredMana, "Stored:", formatManaBalanceFull, setFormatManaBalanceFull),
manaFactory(availableDecayMana, "Decay:", formatManaBalanceFull, setFormatManaBalanceFull),
manaFactory(availablePotentialMana, "Potential:", formatManaBalanceFull, setFormatManaBalanceFull),
manaFactory(blockIssuanceCredits, "Block issuance credits:", formatManaBalanceFull, setFormatManaBalanceFull),
manaFactory(manaRewards, "Mana rewards:", formatManaBalanceFull, setFormatManaBalanceFull),
manaFactory(availableStoredMana, "Stored:", isFormat.availableStoredMana, toggleFormat("availableStoredMana")),
manaFactory(availableDecayMana, "Decay:", isFormat.availableDecayMana, toggleFormat("availableDecayMana")),
manaFactory(
availablePotentialMana,
"Potential:",
isFormat.availablePotentialMana,
toggleFormat("availablePotentialMana"),
),
blockIssuanceCredits !== null
? manaFactory(
blockIssuanceCredits,
"Block issuance credits:",
isFormat.blockIssuanceCredits,
toggleFormat("blockIssuanceCredits"),
)
: null,
manaRewards !== null
? manaFactory(manaRewards, "Mana rewards:", isFormat.manaRewards, toggleFormat("manaRewards"))
: null,
]}
/>

<CardInfo
title="Conditionally Locked Mana"
value={formatAmount(conditionallyLockedManaSum, manaInfo, isFormat.conditionallyLockedMana)}
onClickValue={toggleFormat("conditionallyLockedMana")}
copyValue={String(conditionallyLockedManaSum)}
options={{ headerDirectionRow: true }}
details={[
manaFactory(conditionalStoredMana, "Stored:", formatStorageBalanceFull, setFormatStorageBalanceFull),
manaFactory(conditionalDecayMana, "Decay:", formatStorageBalanceFull, setFormatStorageBalanceFull),
manaFactory(conditionalPotentialMana, "Potential:", formatStorageBalanceFull, setFormatStorageBalanceFull),
manaFactory(
conditionalStoredMana,
"Stored:",
isFormat.conditionalStoredMana,
toggleFormat("conditionalStoredMana"),
),
manaFactory(conditionalDecayMana, "Decay:", isFormat.conditionalDecayMana, toggleFormat("conditionalDecayMana")),
manaFactory(
conditionalPotentialMana,
"Potential:",
isFormat.conditionalPotentialMana,
toggleFormat("conditionalPotentialMana"),
),
]}
/>
</div>
Expand Down
13 changes: 13 additions & 0 deletions client/src/helpers/numberHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,17 @@ export class NumberHelper {
public static isNumber(value?: number | null): boolean {
return value !== null && value !== undefined && !isNaN(value);
}

public static sumValues(...args: (bigint | number | string | null | undefined)[]): number {
return args.reduce<number>((acc, cur) => {
const value = cur || 0; // Convert null or undefined to 0
if (typeof value === "bigint" || typeof value === "number") {
return acc + Number(value);
} else if (typeof value === "string") {
return acc + Number(value) || 0;
} else {
return acc;
}
}, 0);
}
}

0 comments on commit b0f9ed0

Please sign in to comment.