mirror of
https://github.com/pezkuwichain/pezkuwi-sdk-ui.git
synced 2026-07-17 21:45:46 +00:00
d949863789
Comprehensive web interface for interacting with Pezkuwi blockchain. Features: - Blockchain explorer - Wallet management - Staking interface - Governance participation - Developer tools Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
119 lines
3.8 KiB
TypeScript
119 lines
3.8 KiB
TypeScript
// Copyright 2017-2026 @pezkuwi/app-staking authors & contributors
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
import type { DeriveHeartbeats, DeriveStakingOverview } from '@pezkuwi/api-derive/types';
|
|
import type { StakerState } from '@pezkuwi/react-hooks/types';
|
|
import type { BN } from '@pezkuwi/util';
|
|
import type { NominatedByMap, SortedTargets } from '../types.js';
|
|
|
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
|
|
import { Button, ToggleGroup } from '@pezkuwi/react-components';
|
|
import { useApi, useBlockAuthors, useCall } from '@pezkuwi/react-hooks';
|
|
|
|
import { useTranslation } from '../translate.js';
|
|
import ActionsBanner from './ActionsBanner.js';
|
|
import CurrentList from './CurrentList.js';
|
|
import Summary from './Summary.js';
|
|
|
|
interface Props {
|
|
className?: string;
|
|
favorites: string[];
|
|
hasAccounts: boolean;
|
|
hasQueries: boolean;
|
|
minCommission?: BN;
|
|
nominatedBy?: NominatedByMap;
|
|
ownStashes?: StakerState[];
|
|
paraValidators?: Record<string, boolean>;
|
|
stakingOverview?: DeriveStakingOverview;
|
|
targets: SortedTargets;
|
|
toggleFavorite: (address: string) => void;
|
|
toggleLedger?: () => void;
|
|
toggleNominatedBy: () => void;
|
|
}
|
|
|
|
const EMPTY_PARA_VALS: Record<string, boolean> = {};
|
|
const EMPTY_BY_AUTHOR: Record<string, string> = {};
|
|
const EMPTY_ERA_POINTS: Record<string, string> = {};
|
|
|
|
function Overview ({ className = '', favorites, hasAccounts, hasQueries, minCommission, nominatedBy, ownStashes, paraValidators, stakingOverview, targets, toggleFavorite, toggleLedger, toggleNominatedBy }: Props): React.ReactElement<Props> {
|
|
const { t } = useTranslation();
|
|
const { api } = useApi();
|
|
const { byAuthor, eraPoints } = useBlockAuthors();
|
|
const [intentIndex, _setIntentIndex] = useState(0);
|
|
const [typeIndex, setTypeIndex] = useState(1);
|
|
const recentlyOnline = useCall<DeriveHeartbeats>(api.derive.imOnline?.receivedHeartbeats);
|
|
|
|
const setIntentIndex = useCallback(
|
|
(index: number): void => {
|
|
index && toggleNominatedBy();
|
|
_setIntentIndex(index);
|
|
},
|
|
[toggleNominatedBy]
|
|
);
|
|
|
|
const filterOptions = useRef([
|
|
{ text: t('Own validators'), value: 'mine' },
|
|
{ text: t('All validators'), value: 'all' }
|
|
]);
|
|
|
|
const intentOptions = useRef([
|
|
{ text: t('Active'), value: 'active' },
|
|
{ text: t('Waiting'), value: 'waiting' }
|
|
]);
|
|
|
|
const ownStashIds = useMemo(
|
|
() => ownStashes?.map(({ stashId }) => stashId),
|
|
[ownStashes]
|
|
);
|
|
|
|
useEffect((): void => {
|
|
toggleLedger && toggleLedger();
|
|
}, [toggleLedger]);
|
|
|
|
const isOwn = typeIndex === 0;
|
|
|
|
return (
|
|
<div className={`${className} staking--Overview`}>
|
|
<Summary
|
|
stakingOverview={stakingOverview}
|
|
targets={targets}
|
|
/>
|
|
{hasAccounts && (ownStashes?.length === 0) && (
|
|
<ActionsBanner />
|
|
)}
|
|
<Button.Group>
|
|
<ToggleGroup
|
|
onChange={setTypeIndex}
|
|
options={filterOptions.current}
|
|
value={typeIndex}
|
|
/>
|
|
<ToggleGroup
|
|
onChange={setIntentIndex}
|
|
options={intentOptions.current}
|
|
value={intentIndex}
|
|
/>
|
|
</Button.Group>
|
|
<CurrentList
|
|
byAuthor={intentIndex === 0 ? byAuthor : EMPTY_BY_AUTHOR}
|
|
eraPoints={intentIndex === 0 ? eraPoints : EMPTY_ERA_POINTS}
|
|
favorites={favorites}
|
|
hasQueries={hasQueries}
|
|
isIntentions={intentIndex === 1}
|
|
isOwn={isOwn}
|
|
key={intentIndex}
|
|
minCommission={intentIndex === 0 ? minCommission : undefined}
|
|
nominatedBy={intentIndex === 1 ? nominatedBy : undefined}
|
|
ownStashIds={ownStashIds}
|
|
paraValidators={(intentIndex === 0 && paraValidators) || EMPTY_PARA_VALS}
|
|
recentlyOnline={intentIndex === 0 ? recentlyOnline : undefined}
|
|
stakingOverview={stakingOverview}
|
|
targets={targets}
|
|
toggleFavorite={toggleFavorite}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default React.memo(Overview);
|