mirror of
https://github.com/pezkuwichain/pezkuwi-sdk-ui.git
synced 2026-07-22 09:05:47 +00:00
Initial commit: Pezkuwi SDK UI
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>
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
// 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);
|
||||
Reference in New Issue
Block a user