mirror of
https://github.com/pezkuwichain/pezkuwi-sdk-ui.git
synced 2026-06-14 08:41:03 +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>
102 lines
2.9 KiB
TypeScript
102 lines
2.9 KiB
TypeScript
// Copyright 2017-2026 @pezkuwi/react-params authors & contributors
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
import type { Props } from '../types.js';
|
|
|
|
import React, { useCallback, useMemo, useRef } from 'react';
|
|
|
|
import { Dropdown } from '@pezkuwi/react-components';
|
|
import { GenericVote } from '@pezkuwi/types';
|
|
import { isBn, isNumber } from '@pezkuwi/util';
|
|
|
|
import { useTranslation } from '../translate.js';
|
|
import Bare from './Bare.js';
|
|
|
|
const AYE_MASK = 0b10000000;
|
|
|
|
// In this approach, it will avoid using additional local states and instead rely directly on the parent-provided values and methods.
|
|
function Vote ({ className = '', defaultValue: { value }, isDisabled, isError, onChange, withLabel }: Props): React.ReactElement<Props> {
|
|
const { t } = useTranslation();
|
|
|
|
// Derive aye and conviction from the value prop
|
|
const { aye, conviction } = useMemo(() => {
|
|
// Logic sucks here, but to be honest, can not find other way to do it
|
|
const resolvedAye = value instanceof GenericVote
|
|
? value.isAye
|
|
: isBn(value)
|
|
? !!(value.toNumber() & AYE_MASK)
|
|
: isNumber(value)
|
|
? !!(value & AYE_MASK)
|
|
: typeof value === 'object' && value !== null && 'aye' in value
|
|
? !!value.aye
|
|
: true;
|
|
|
|
const resolvedConviction = value instanceof GenericVote
|
|
? value.conviction.index
|
|
: typeof value === 'object' && value !== null && 'conviction' in value
|
|
? Number(value.conviction)
|
|
: 0;
|
|
|
|
return {
|
|
aye: resolvedAye,
|
|
conviction: resolvedConviction
|
|
};
|
|
}, [value]);
|
|
|
|
const onChangeVote = useCallback(
|
|
(newAye: boolean) => {
|
|
onChange?.({ isValid: true, value: { aye: newAye, conviction } });
|
|
},
|
|
[conviction, onChange]
|
|
);
|
|
|
|
const onChangeConviction = useCallback(
|
|
(newConviction: number) => {
|
|
onChange?.({ isValid: true, value: { aye, conviction: newConviction } });
|
|
},
|
|
[aye, onChange]
|
|
);
|
|
|
|
const optAyeRef = useRef([
|
|
{ text: t('Nay'), value: false },
|
|
{ text: t('Aye'), value: true }
|
|
]);
|
|
|
|
const optConvRef = useRef([
|
|
{ text: t('None'), value: 0 },
|
|
{ text: t('Locked1x'), value: 1 },
|
|
{ text: t('Locked2x'), value: 2 },
|
|
{ text: t('Locked3x'), value: 3 },
|
|
{ text: t('Locked4x'), value: 4 },
|
|
{ text: t('Locked5x'), value: 5 },
|
|
{ text: t('Locked6x'), value: 6 }
|
|
]);
|
|
|
|
return (
|
|
<Bare className={className}>
|
|
<Dropdown
|
|
className='full'
|
|
defaultValue={aye}
|
|
isDisabled={isDisabled}
|
|
isError={isError}
|
|
label={t('aye: bool')}
|
|
onChange={onChangeVote}
|
|
options={optAyeRef.current}
|
|
withLabel={withLabel}
|
|
/>
|
|
<Dropdown
|
|
className='full'
|
|
defaultValue={conviction}
|
|
isDisabled={isDisabled}
|
|
isError={isError}
|
|
label={t('conviction: Conviction')}
|
|
onChange={onChangeConviction}
|
|
options={optConvRef.current}
|
|
withLabel={withLabel}
|
|
/>
|
|
</Bare>
|
|
);
|
|
}
|
|
|
|
export default React.memo(Vote);
|