mirror of
https://github.com/lux-tel/websites.git
synced 2026-10-30 20:31:36 +00:00
115 lines
4.4 KiB
TypeScript
115 lines
4.4 KiB
TypeScript
'use client';
|
|
|
|
import { PubKey } from '@session/ui/components/PubKey';
|
|
import { formatPercentage } from '@/lib/locale-client';
|
|
import { ButtonDataTestId } from '@/testing/data-test-ids';
|
|
import { SENT_DECIMALS, SENT_SYMBOL } from '@session/contracts';
|
|
import type { GetOpenNodesResponse } from '@session/sent-staking-js/client';
|
|
import { Loading } from '@session/ui/components/loading';
|
|
import { Button, ButtonSkeleton } from '@session/ui/ui/button';
|
|
import { bigIntToNumber, formatNumber } from '@session/util-crypto/maths';
|
|
import { useTranslations } from 'next-intl';
|
|
import { useMemo } from 'react';
|
|
import { ActionModuleRow, ActionModuleRowSkeleton } from '@/components/ActionModule';
|
|
import { useStakingBackendSuspenseQuery } from '@/lib/sent-staking-backend-client';
|
|
import { getOpenNodes } from '@/lib/queries/getOpenNodes';
|
|
import { areHexesEqual } from '@session/util-crypto/string';
|
|
|
|
export default function NodeStaking({ nodeId }: { nodeId: string }) {
|
|
const { data, isLoading } = useStakingBackendSuspenseQuery(getOpenNodes);
|
|
|
|
const node = useMemo(() => {
|
|
return data?.nodes?.find((node) => areHexesEqual(node.service_node_pubkey, nodeId));
|
|
}, [data]);
|
|
|
|
return isLoading ? (
|
|
<Loading />
|
|
) : node ? (
|
|
<NodeStakingForm node={node} />
|
|
) : (
|
|
<span>Node not found</span>
|
|
);
|
|
}
|
|
|
|
export function NodeStakingForm({ node }: { node: GetOpenNodesResponse['nodes'][number] }) {
|
|
// const dictionary = useTranslations('actionModules.node');
|
|
const generalDictionary = useTranslations('general');
|
|
const sessionNodeDictionary = useTranslations('sessionNodes.general');
|
|
const sessionNodeStakingDictionary = useTranslations('sessionNodes.staking');
|
|
|
|
const formattedTotalStakedAmount = useMemo(() => {
|
|
if (!node.contributions || node.contributions.length === 0) return '0';
|
|
const totalStaked = node.contributions.reduce(
|
|
(acc, contributor) => acc + bigIntToNumber(contributor.amount, SENT_DECIMALS),
|
|
0
|
|
);
|
|
return formatNumber(totalStaked);
|
|
}, [node.contributions]);
|
|
|
|
return (
|
|
<div className="flex flex-col gap-4">
|
|
{/*<ActionModuleRow*/}
|
|
{/* label={dictionary('contributors')}*/}
|
|
{/* tooltip={dictionary('contributorsTooltip')}*/}
|
|
{/*>*/}
|
|
{/* <span className="flex flex-row flex-wrap items-center gap-2 align-middle">*/}
|
|
{/* <NodeContributorList contributors={node.contributions} forceExpand showEmptySlots />*/}
|
|
{/* </span>*/}
|
|
{/*</ActionModuleRow>*/}
|
|
<ActionModuleRow
|
|
label={sessionNodeStakingDictionary('stakedAmount')}
|
|
tooltip={sessionNodeStakingDictionary('stakedAmountDescription')}
|
|
>
|
|
{formattedTotalStakedAmount} {SENT_SYMBOL}
|
|
</ActionModuleRow>
|
|
<ActionModuleRow
|
|
label={sessionNodeDictionary('publicKeyShort')}
|
|
tooltip={sessionNodeDictionary('publicKeyDescription')}
|
|
>
|
|
<PubKey pubKey={node.service_node_pubkey} force="collapse" alwaysShowCopyButton />
|
|
</ActionModuleRow>
|
|
<ActionModuleRow
|
|
label={sessionNodeDictionary('operatorAddress')}
|
|
tooltip={sessionNodeDictionary('operatorAddressTooltip')}
|
|
>
|
|
{node.contributions[0]?.address ? (
|
|
<PubKey pubKey={node.contributions[0]?.address} force="collapse" alwaysShowCopyButton />
|
|
) : null}
|
|
</ActionModuleRow>
|
|
<ActionModuleRow
|
|
label={sessionNodeDictionary('operatorFee')}
|
|
tooltip={sessionNodeDictionary('operatorFeeDescription')}
|
|
>
|
|
{/** TODO: replace this */}
|
|
{formatPercentage(node.fee / 10000)}
|
|
</ActionModuleRow>
|
|
{/* <SessionTokenInput
|
|
type="number"
|
|
value={value}
|
|
onChange={(e) => setValue(parseFloat(e.target.value))}
|
|
min={node.minContribution}
|
|
max={node.maxContribution}
|
|
className="rounded-xl py-12 text-right text-3xl font-medium"
|
|
/> */}
|
|
<Button data-testid={ButtonDataTestId.Stake_Submit} disabled rounded="lg" size="lg">
|
|
{/* {dictionary('button.submit', { amount: value })} */}
|
|
{generalDictionary('comingSoon')}
|
|
</Button>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function NodeStakingFormSkeleton() {
|
|
return (
|
|
<div className="flex flex-col gap-4">
|
|
<ActionModuleRowSkeleton />
|
|
<ActionModuleRowSkeleton />
|
|
<ActionModuleRowSkeleton />
|
|
<ActionModuleRowSkeleton />
|
|
<ActionModuleRowSkeleton />
|
|
<ActionModuleRowSkeleton />
|
|
<ButtonSkeleton rounded="lg" size="lg" />
|
|
</div>
|
|
);
|
|
}
|