Society bid modal (& unbid, bidder overview counter) (#3194)
* Society bid modal (& bidder counter) * Add unbid button (when bidder)
This commit is contained in:
parent
3b84ab5863
commit
b1def01f5b
@ -4,7 +4,7 @@
|
||||
|
||||
import { Route } from './types';
|
||||
|
||||
import Component from '@polkadot/app-society';
|
||||
import Component, { useCounter } from '@polkadot/app-society';
|
||||
|
||||
export default function create (t: <T = string> (key: string, text: string, options: { ns: string }) => T): Route {
|
||||
return {
|
||||
@ -17,6 +17,7 @@ export default function create (t: <T = string> (key: string, text: string, opti
|
||||
},
|
||||
icon: 'hand-spock',
|
||||
name: 'society',
|
||||
text: t<string>('nav.society', 'Society', { ns: 'apps-routing' })
|
||||
text: t<string>('nav.society', 'Society', { ns: 'apps-routing' }),
|
||||
useCounter
|
||||
};
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ function Delegate ({ amount: _amount, conviction: _conviction, delegatedAccount:
|
||||
header= {t<string>('Delegate democracy vote')}
|
||||
size='large'
|
||||
>
|
||||
<Modal.Content className='ui--signer-Signer-Content'>
|
||||
<Modal.Content>
|
||||
<Modal.Columns>
|
||||
<Modal.Column>
|
||||
<InputAddress
|
||||
|
||||
@ -21,7 +21,7 @@ function Undelegate ({ accountDelegating, onClose }: Props): React.ReactElement<
|
||||
header= {t<string>('Undelegate')}
|
||||
size='large'
|
||||
>
|
||||
<Modal.Content className='ui--signer-Signer-Content'>
|
||||
<Modal.Content>
|
||||
<Modal.Columns>
|
||||
<Modal.Column>
|
||||
<InputAddress
|
||||
|
||||
@ -4,15 +4,29 @@
|
||||
|
||||
import { Bid } from '@polkadot/types/interfaces';
|
||||
|
||||
import React from 'react';
|
||||
import { AddressSmall } from '@polkadot/react-components';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { AddressSmall, TxButton } from '@polkadot/react-components';
|
||||
import { useAccounts } from '@polkadot/react-hooks';
|
||||
import { FormatBalance } from '@polkadot/react-query';
|
||||
|
||||
import { useTranslation } from '../translate';
|
||||
|
||||
interface Props {
|
||||
index: number;
|
||||
value: Bid;
|
||||
}
|
||||
|
||||
function BidRow ({ value: { kind, value, who } }: Props): React.ReactElement<Props> {
|
||||
function BidRow ({ index, value: { kind, value, who } }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { allAccounts } = useAccounts();
|
||||
const [isBidder, setIsBidder] = useState(false);
|
||||
|
||||
useEffect((): void => {
|
||||
const address = who.toString();
|
||||
|
||||
setIsBidder(allAccounts.some((accountId) => accountId === address));
|
||||
}, [allAccounts, who]);
|
||||
|
||||
return (
|
||||
<tr>
|
||||
<td className='all top'>
|
||||
@ -24,6 +38,16 @@ function BidRow ({ value: { kind, value, who } }: Props): React.ReactElement<Pro
|
||||
<td className='number top'>
|
||||
<FormatBalance value={value} />
|
||||
</td>
|
||||
<td className='button'>
|
||||
<TxButton
|
||||
accountId={who}
|
||||
icon='times'
|
||||
isDisabled={!isBidder}
|
||||
label={t<string>('Unbid')}
|
||||
params={[index]}
|
||||
tx='society.unbid'
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
69
packages/page-society/src/Overview/BidNew.tsx
Normal file
69
packages/page-society/src/Overview/BidNew.tsx
Normal file
@ -0,0 +1,69 @@
|
||||
// Copyright 2017-2020 @polkadot/app-society authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import BN from 'bn.js';
|
||||
import React, { useState } from 'react';
|
||||
import { InputAddress, InputBalance, Modal, TxButton } from '@polkadot/react-components';
|
||||
|
||||
import { useTranslation } from '../translate';
|
||||
|
||||
interface Props {
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
function BidNew ({ onClose }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const [amount, setAmount] = useState<BN | undefined>();
|
||||
const [accountId, setAccount] = useState<string | null | undefined>();
|
||||
|
||||
return (
|
||||
<Modal
|
||||
header= {t<string>('Bid to join')}
|
||||
size='large'
|
||||
>
|
||||
<Modal.Content>
|
||||
<Modal.Columns>
|
||||
<Modal.Column>
|
||||
<InputAddress
|
||||
help={t<string>('The actual account you wish to sub,it the bid with')}
|
||||
label={t<string>('bid account')}
|
||||
onChange={setAccount}
|
||||
type='account'
|
||||
/>
|
||||
</Modal.Column>
|
||||
<Modal.Column>
|
||||
<p>{t<string>('Your canidate/bid account. Once accepted this account will become a member.')}</p>
|
||||
</Modal.Column>
|
||||
</Modal.Columns>
|
||||
<Modal.Columns>
|
||||
<Modal.Column>
|
||||
<InputBalance
|
||||
autoFocus
|
||||
help={t<string>('The amount to associate with your bid, should be less than the pot.')}
|
||||
label={t<string>('bid amount')}
|
||||
onChange={setAmount}
|
||||
/>
|
||||
</Modal.Column>
|
||||
<Modal.Column>
|
||||
<p>{t<string>('The amount to tie to your bid. The lowest bidder moves forward.')}</p>
|
||||
</Modal.Column>
|
||||
</Modal.Columns>
|
||||
</Modal.Content>
|
||||
<Modal.Actions onCancel={onClose}>
|
||||
<TxButton
|
||||
accountId={accountId}
|
||||
icon='sign-in-alt'
|
||||
isDisabled={!amount}
|
||||
isPrimary
|
||||
label={t<string>('Bid')}
|
||||
onStart={onClose}
|
||||
params={[amount]}
|
||||
tx='society.bid'
|
||||
/>
|
||||
</Modal.Actions>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export default React.memo(BidNew);
|
||||
@ -23,7 +23,8 @@ function Bids ({ className }: Props): React.ReactElement<Props> {
|
||||
const header = useMemo(() => [
|
||||
[t('bids'), 'start'],
|
||||
[t('kind')],
|
||||
[t('value')]
|
||||
[t('value')],
|
||||
[]
|
||||
], [t]);
|
||||
|
||||
return (
|
||||
@ -32,8 +33,9 @@ function Bids ({ className }: Props): React.ReactElement<Props> {
|
||||
empty={bids && t<string>('No bids')}
|
||||
header={header}
|
||||
>
|
||||
{bids?.map((bid): React.ReactNode => (
|
||||
{bids?.map((bid, index): React.ReactNode => (
|
||||
<BidRow
|
||||
index={index}
|
||||
key={bid.who.toString()}
|
||||
value={bid}
|
||||
/>
|
||||
|
||||
@ -6,27 +6,43 @@ import { DeriveSociety } from '@polkadot/api-derive/types';
|
||||
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { useApi, useCall } from '@polkadot/react-hooks';
|
||||
import { Button } from '@polkadot/react-components';
|
||||
import { useApi, useCall, useToggle } from '@polkadot/react-hooks';
|
||||
|
||||
import useMembers from '../useMembers';
|
||||
import BidNew from './BidNew';
|
||||
import Bids from './Bids';
|
||||
import Candidates from './Candidates';
|
||||
import Defender from './Defender';
|
||||
import Members from './Members';
|
||||
import Summary from './Summary';
|
||||
|
||||
import { useTranslation } from '../translate';
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
function Overview ({ className }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const info = useCall<DeriveSociety>(api.derive.society.info, []);
|
||||
const { allMembers, isMember, ownMembers } = useMembers();
|
||||
const [isBidOpen, toggleBidOpen] = useToggle();
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
<Summary info={info} />
|
||||
<Button.Group>
|
||||
<Button
|
||||
icon='plus'
|
||||
label={t<string>('Submit bid')}
|
||||
onClick={toggleBidOpen}
|
||||
/>
|
||||
{isBidOpen && (
|
||||
<BidNew onClose={toggleBidOpen} />
|
||||
)}
|
||||
</Button.Group>
|
||||
<Defender
|
||||
info={info}
|
||||
isMember={isMember}
|
||||
|
||||
@ -8,12 +8,15 @@ import { Tabs } from '@polkadot/react-components';
|
||||
|
||||
import Overview from './Overview';
|
||||
import { useTranslation } from './translate';
|
||||
import useCounter from './useCounter';
|
||||
|
||||
interface Props {
|
||||
basePath: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export { useCounter };
|
||||
|
||||
function SocietyApp ({ basePath, className }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const items = useMemo(() => [
|
||||
|
||||
14
packages/page-society/src/useCounter.ts
Normal file
14
packages/page-society/src/useCounter.ts
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright 2017-2020 @polkadot/app-society authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { Bid } from '@polkadot/types/interfaces';
|
||||
|
||||
import { useApi, useCall } from '@polkadot/react-hooks';
|
||||
|
||||
export default function useCounter (): number {
|
||||
const { api } = useApi();
|
||||
const bids = useCall<Bid[]>(api.query.society?.bids, []);
|
||||
|
||||
return bids?.length || 0;
|
||||
}
|
||||
@ -53,7 +53,7 @@ function BondExtra ({ controllerId, onClose, stakingInfo, stashId }: Props): Rea
|
||||
header= {t<string>('Bond more funds')}
|
||||
size='large'
|
||||
>
|
||||
<Modal.Content className='ui--signer-Signer-Content'>
|
||||
<Modal.Content>
|
||||
<Modal.Columns>
|
||||
<Modal.Column>
|
||||
<InputAddress
|
||||
|
||||
@ -33,7 +33,7 @@ function Unbond ({ className = '', controllerId, onClose, stakingLedger, stashId
|
||||
header={t<string>('Unbond funds')}
|
||||
size='large'
|
||||
>
|
||||
<Modal.Content className='ui--signer-Signer-Content'>
|
||||
<Modal.Content>
|
||||
<Modal.Columns>
|
||||
<Modal.Column>
|
||||
<InputAddress
|
||||
|
||||
@ -25,7 +25,7 @@ function Validate ({ controllerId, onClose, stashId }: Props): React.ReactElemen
|
||||
header={t<string>('Set validator preferences')}
|
||||
size='large'
|
||||
>
|
||||
<Modal.Content className='ui--signer-Signer-Content'>
|
||||
<Modal.Content>
|
||||
<ValidatePartial
|
||||
controllerId={controllerId}
|
||||
onChange={setTx}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user