Adjust styled injection (assets, bounties, calendar, claims) (#8808)

* Adjust styled injection (assets, bounties, calendar, claims)

* Build fixes
This commit is contained in:
Jaco 2023-01-15 11:03:06 +02:00 committed by GitHub
parent 6b048aa849
commit 9f401cc8ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 156 additions and 109 deletions

View File

@ -63,7 +63,7 @@ function Balances ({ className, infos = [] }: Props): React.ReactElement<Props>
}, [completeInfos, infoIndex]);
return (
<div className={className}>
<StyledDiv className={className}>
<Table
empty={info && balances && t<string>('No accounts with balances found for the asset')}
filter={assetOptions.length
@ -91,12 +91,14 @@ function Balances ({ className, infos = [] }: Props): React.ReactElement<Props>
/>
))}
</Table>
</div>
</StyledDiv>
);
}
export default React.memo(styled(Balances)`
const StyledDiv = styled.div`
table {
overflow: auto;
}
`);
`;
export default React.memo(Balances);

View File

@ -1,6 +1,8 @@
// Copyright 2017-2023 @polkadot/app-bounties authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { BN } from '@polkadot/util';
import React, { useMemo, useRef } from 'react';
import styled from 'styled-components';
@ -33,7 +35,7 @@ function Bounties ({ className }: Props): React.ReactElement {
]);
return (
<div className={className}>
<StyledDiv className={className}>
<Summary info={info} />
<Button.Group>
<BountyCreate />
@ -45,7 +47,7 @@ function Bounties ({ className }: Props): React.ReactElement {
>
{sorted && info.bestNumber && sorted.map(({ bounty, description, index, proposals }) => (
<Bounty
bestNumber={info.bestNumber}
bestNumber={info.bestNumber as BN}
bounty={bounty}
description={description}
index={index}
@ -54,11 +56,11 @@ function Bounties ({ className }: Props): React.ReactElement {
/>
))}
</Table>
</div>
</StyledDiv>
);
}
export default React.memo(styled(Bounties)`
const StyledDiv = styled.div`
.bounties-table-wrapper table {
tr {
td, &:not(.filter) th {
@ -80,4 +82,6 @@ export default React.memo(styled(Bounties)`
filter: initial;
opacity: 1;
}
`);
`;
export default React.memo(Bounties);

View File

@ -2,7 +2,8 @@
// SPDX-License-Identifier: Apache-2.0
import type { DeriveCollectiveProposal } from '@polkadot/api-derive/types';
import type { BlockNumber, Bounty as BountyType, BountyIndex } from '@polkadot/types/interfaces';
import type { Bounty as BountyType, BountyIndex } from '@polkadot/types/interfaces';
import type { BN } from '@polkadot/util';
import React, { useMemo } from 'react';
import styled from 'styled-components';
@ -24,7 +25,7 @@ import { useTranslation } from './translate';
import VotersColumn from './VotersColumn';
interface Props {
bestNumber: BlockNumber;
bestNumber: BN;
bounty: BountyType;
className?: string;
description: string;
@ -56,7 +57,7 @@ function Bounty ({ bestNumber, bounty, className = '', description, index, propo
return (
<>
<tr className={`${className} isExpanded isFirst ${isExpanded ? '' : 'isLast'}`}>
<StyledTr className={`${className} isExpanded isFirst ${isExpanded ? '' : 'isLast'}`}>
<Table.Column.Id value={index} />
<td
className='description-column'
@ -130,8 +131,8 @@ function Bounty ({ bestNumber, bounty, className = '', description, index, propo
/>
</div>
</td>
</tr>
<tr className={`${className} ${isExpanded ? 'isExpanded isLast' : 'isCollapsed'}`}>
</StyledTr>
<StyledTr className={`${className} ${isExpanded ? 'isExpanded isLast' : 'isCollapsed'}`}>
<td />
<td
className='columar'
@ -192,12 +193,12 @@ function Bounty ({ bestNumber, bounty, className = '', description, index, propo
)}
</td>
<td />
</tr>
</StyledTr>
</>
);
}
export default React.memo(styled(Bounty)`
const StyledTr = styled.tr`
.description-column {
max-width: 200px;
@ -264,4 +265,6 @@ export default React.memo(styled(Bounty)`
display: flex;
justify-content: space-between;
}
`);
`;
export default React.memo(Bounty);

View File

@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
import type { DeriveCollectiveProposal } from '@polkadot/api-derive/types';
import type { Balance, BlockNumber, BountyIndex, BountyStatus } from '@polkadot/types/interfaces';
import type { Balance, BountyIndex, BountyStatus } from '@polkadot/types/interfaces';
import type { BN } from '@polkadot/util';
import React, { useMemo } from 'react';
@ -15,7 +15,7 @@ import BountyInitiateVoting from './BountyInitiateVoting';
import ProposeCuratorAction from './ProposeCuratorAction';
interface Props {
bestNumber: BlockNumber;
bestNumber: BN;
description: string;
fee?: BN;
index: BountyIndex;

View File

@ -1,12 +1,14 @@
// Copyright 2017-2023 @polkadot/app-bounties authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { BountyIndex, BountyStatus } from '@polkadot/types/interfaces';
import type { BN } from '@polkadot/util';
import React, { useCallback, useMemo, useRef, useState } from 'react';
import { DeriveCollectiveProposal } from '@polkadot/api-derive/types';
import { Menu, Popup } from '@polkadot/react-components';
import { useCollectiveMembers, useToggle } from '@polkadot/react-hooks';
import { BlockNumber, BountyIndex, BountyStatus } from '@polkadot/types/interfaces';
import { determineUnassignCuratorAction } from '../helpers';
import { useBountyStatus, useUserRole } from '../hooks';
@ -19,7 +21,7 @@ import GiveUp from './GiveUp';
import SlashCurator from './SlashCurator';
interface Props {
bestNumber: BlockNumber;
bestNumber: BN;
className?: string;
description: string;
index: BountyIndex;

View File

@ -30,17 +30,19 @@ function VotingDescriptionInfo ({ className, proposal, status }: Props): React.R
});
return (
<div
<StyledDiv
className={className}
data-testid='voting-description'
>
{bestProposalName && votingDescriptions.current[bestProposalName] &&
<LabelHelp help={votingDescriptions.current[bestProposalName]} />
}
</div>
</StyledDiv>
);
}
export default React.memo(styled(VotingDescriptionInfo)`
const StyledDiv = styled.div`
margin-left: 0.2rem;
`);
`;
export default React.memo(VotingDescriptionInfo);

View File

@ -14,17 +14,19 @@ function VotingLink ({ className }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
return (
<a
<StyledA
className={className}
href='#/council/motions'
>
{t<string>('Voting')}
</a>
</StyledA>
);
}
export default React.memo(styled(VotingLink)`
const StyledA = styled.a`
line-height: 0.85rem;
font-size: var(--font-size-tiny);
text-decoration: underline;
`);
`;
export default React.memo(VotingLink);

View File

@ -30,7 +30,7 @@ function VotingSummary ({ className, proposal, status }: Props): JSX.Element {
return (
<>
{proposal && (
<div
<StyledDiv
className={className}
data-testid='voting-summary'
>
@ -43,13 +43,13 @@ function VotingSummary ({ className, proposal, status }: Props): JSX.Element {
status={status}
/>
</div>
</div>
</StyledDiv>
)}
</>
);
}
export default React.memo(styled(VotingSummary)`
const StyledDiv = styled.div`
.voting-summary-text {
font-size: var(--font-size-small);
line-height: 1.5rem;
@ -67,4 +67,6 @@ export default React.memo(styled(VotingSummary)`
align-items: center;
line-height: 1.5rem;
}
`);
`;
export default React.memo(VotingSummary);

View File

@ -1,7 +1,7 @@
// Copyright 2017-2023 @polkadot/app-bounties authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { BlockNumber, BountyStatus } from '@polkadot/types/interfaces';
import type { BountyStatus } from '@polkadot/types/interfaces';
import React, { useMemo } from 'react';
@ -13,7 +13,7 @@ import { useTranslation } from '../translate';
import BountyInfo from './BountyInfo';
interface Props {
bestNumber: BlockNumber;
bestNumber: BN;
blocksUntilUpdate?: BN;
status: BountyStatus;
}

View File

@ -11,14 +11,14 @@ import { Icon } from '@polkadot/react-components';
import { bountySvgColor } from '../theme';
interface Props {
className: '';
className?: string;
description: string;
type?: 'info' | 'warning';
}
function BountyInfo ({ className = '', description, type = 'info' }: Props): React.ReactElement<Props> {
return (
<div className={className}>
<StyledDiv className={className}>
{type === 'warning' && (
<div className='info-icon'>
<Icon icon={'exclamation-triangle'} />
@ -27,18 +27,19 @@ function BountyInfo ({ className = '', description, type = 'info' }: Props): Rea
<div className='description'>
{description}
</div>
</div>
</StyledDiv>
);
}
export default React.memo(styled(BountyInfo)(({ theme }: ThemeProps) => `
const StyledDiv = styled.div(({ theme }: ThemeProps) => `
display: flex;
align-items: center;
font-size: var(--font-size-small);
line-height: 1.5rem;
.info-icon{
.info-icon {
margin-right: 0.2rem;
svg {
color: ${bountySvgColor[theme.theme]};
}
@ -51,4 +52,6 @@ export default React.memo(styled(BountyInfo)(({ theme }: ThemeProps) => `
color: var(--color-label);
word-wrap: break-word;
}
`));
`);
export default React.memo(BountyInfo);

View File

@ -16,17 +16,19 @@ interface Props {
function BountyStatusView ({ bountyStatus, className = '' }: Props): React.ReactElement<Props> {
return (
<div
<StyledDiv
className={className}
data-testid={'bountyStatus'}
>
{insertSpaceBeforeCapitalLetter(bountyStatus)}
<LabelHelp />
</div>
</StyledDiv>
);
}
export default React.memo(styled(BountyStatusView)`
const StyledDiv = styled.div`
display: flex;
align-items: center;
`);
`;
export default React.memo(BountyStatusView);

View File

@ -12,18 +12,20 @@ interface Props {
function Description ({ className = '', dataTestId = '', description }: Props): JSX.Element {
return (
<div
<StyledDiv
className={className}
data-testid={dataTestId}
>
{description}
</div>
</StyledDiv>
);
}
export default React.memo(styled(Description)`
const StyledDiv = styled.div`
margin-top: 0.28rem;
font-size: var(--font-size-tiny);
line-height: 0.85rem;
color: var(--color-label);
`);
`;
export default React.memo(Description);

View File

@ -42,7 +42,7 @@ function VotersColumn ({ className, option, proposals, status }: Props): React.R
return (
<>
{proposal &&
<div className={className}>
<StyledDiv className={className}>
<div className='vote-numbers'>
<span className='vote-numbers-icon'><Icon icon={icons[option]} /></span>
<span className='vote-numbers-label'>
@ -51,12 +51,13 @@ function VotersColumn ({ className, option, proposals, status }: Props): React.R
</span>
</div>
{voters}
</div>}
</StyledDiv>
}
</>
);
}
export default React.memo(styled(VotersColumn)`
const StyledDiv = styled.div`
width: 50%;
.vote-numbers {
@ -78,4 +79,6 @@ export default React.memo(styled(VotersColumn)`
text-transform: uppercase;
color: var(--color-label);
}
`);
`;
export default React.memo(VotersColumn);

View File

@ -1,7 +1,7 @@
// Copyright 2017-2023 @polkadot/app-calendar authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { EntryInfo } from './types';
import type { EntryInfoTyped } from './types';
import React, { useCallback, useMemo, useRef } from 'react';
import styled from 'styled-components';
@ -18,7 +18,7 @@ interface Props {
date: Date;
hasNextDay: boolean;
now: Date;
scheduled: EntryInfo[];
scheduled: EntryInfoTyped[];
setNextDay: () => void;
setPrevDay: () => void;
setView: (v: boolean) => void;
@ -54,7 +54,7 @@ function Day ({ className, date, hasNextDay, now, scheduled, setNextDay, setPrev
);
return (
<div className={className}>
<StyledDiv className={className}>
<h1>
<div>
<Button
@ -89,11 +89,11 @@ function Day ({ className, date, hasNextDay, now, scheduled, setNextDay, setPrev
/>
)}
</div>
</div>
</StyledDiv>
);
}
export default React.memo(styled(Day)`
const StyledDiv = styled.div`
flex: 1;
.dayHeader {
@ -107,4 +107,6 @@ export default React.memo(styled(Day)`
.hoursContainer {
z-index: 1;
}
`);
`;
export default React.memo(Day);

View File

@ -39,7 +39,7 @@ function DayHour ({ className = '', date, hour, index, minutes, scheduled }: Pro
const hourStr = `${` ${hour}`.slice(-2)} ${hour >= 12 ? 'pm' : 'am'}`;
return (
<div className={`${className}${filtered.length ? ' hasItems' : ''}`}>
<StyledDiv className={`${className}${filtered.length ? ' hasItems' : ''}`}>
<div className={`hourLabel${filtered.length ? ' highlight--color' : ''}`}>{hourStr}</div>
<div className='hourContainer'>
{filtered.map((item, index): React.ReactNode => (
@ -49,11 +49,11 @@ function DayHour ({ className = '', date, hour, index, minutes, scheduled }: Pro
/>
))}
</div>
</div>
</StyledDiv>
);
}
export default React.memo(styled(DayHour)`
const StyledDiv = styled.div`
align-items: center;
display: flex;
position: relative;
@ -91,4 +91,6 @@ export default React.memo(styled(DayHour)`
opacity: 1;
padding: 0.7rem 1rem;
}
`);
`;
export default React.memo(DayHour);

View File

@ -178,7 +178,7 @@ function DayItem ({ className, item: { blockNumber, date, info, type }, showAllE
);
return (
<div className={className}>
<StyledDiv className={className}>
{showAllEvents &&
<div className='itemDate'>{date.toLocaleString(undefined, FORMAT_OPTIONS)}</div>
}
@ -192,11 +192,11 @@ function DayItem ({ className, item: { blockNumber, date, info, type }, showAllE
onClick={_exportCal}
/>
)}
</div>
</StyledDiv>
);
}
export default React.memo(styled(DayItem)`
const StyledDiv = styled.div`
align-items: flex-start;
display: flex;
justify-content: flex-start;
@ -246,4 +246,6 @@ export default React.memo(styled(DayItem)`
padding: 0 0.375rem;
border-radius: 0.25rem;
}
`);
`;
export default React.memo(DayItem);

View File

@ -42,7 +42,7 @@ function Month ({ className, hasNextMonth, lastDay, now, scheduled, setDay, setN
);
return (
<div className={className}>
<StyledDiv className={className}>
<h1>
<div>{monthRef.current[dateMonth.getMonth()]} {dateMonth.getFullYear()}</div>
<Button.Group>
@ -78,11 +78,11 @@ function Month ({ className, hasNextMonth, lastDay, now, scheduled, setDay, setN
))}
</div>
</div>
</div>
</StyledDiv>
);
}
export default React.memo(styled(Month)`
const StyledDiv = styled.div`
flex: 0;
max-width: max-content;
@ -124,4 +124,6 @@ export default React.memo(styled(Month)`
justify-content: space-between;
}
}
`);
`;
export default React.memo(Month);

View File

@ -37,17 +37,17 @@ function MonthDay ({ className = '', dateMonth, day, isCurrent, isDisabled, sche
);
return (
<div
<StyledDiv
className={`day${isDisabled ? ' isDisabled' : (isCurrent ? ' highlight--bg-light highlight--color isSelected' : '')} ${className}`}
onClick={_onClick}
>
{day}
{hasEvents && <div className='eventIndicator highlight--border' />}
</div>
</StyledDiv>
);
}
export default React.memo(styled(MonthDay)`
const StyledDiv = styled.div`
background-color: transparent;
border: 1px solid transparent;
border-radius: 50%;
@ -90,4 +90,6 @@ export default React.memo(styled(MonthDay)`
display: none;
}
}
`);
`;
export default React.memo(MonthDay);

View File

@ -1,7 +1,7 @@
// Copyright 2017-2023 @polkadot/app-calendar authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { EntryInfo } from './types';
import type { EntryInfoTyped } from './types';
import React, { useCallback, useMemo } from 'react';
import styled from 'styled-components';
@ -13,7 +13,7 @@ import { useTranslation } from './translate';
interface Props {
className?: string;
scheduled: EntryInfo[];
scheduled: EntryInfoTyped[];
setView: (v: boolean) => void;
}
@ -30,7 +30,7 @@ function UpcomingEvents ({ className, scheduled, setView }: Props): React.ReactE
);
return (
<div className={className}>
<StyledDiv className={className}>
<h1>
<div>
<Button
@ -53,11 +53,11 @@ function UpcomingEvents ({ className, scheduled, setView }: Props): React.ReactE
);
})}
</ul>
</div>
</StyledDiv>
);
}
export default React.memo(styled(UpcomingEvents)`
const StyledDiv = styled.div`
flex: 0;
max-width: max-content;
@ -72,4 +72,6 @@ export default React.memo(styled(UpcomingEvents)`
.allEventsWrapper {
padding-inline-start: 10px;
}
`);
`;
export default React.memo(UpcomingEvents);

View File

@ -115,7 +115,7 @@ function CalendarApp ({ basePath, className }: Props): React.ReactElement<Props>
);
return (
<main className={className}>
<StyledMain className={className}>
<Tabs
basePath={basePath}
items={itemsRef.current}
@ -154,11 +154,11 @@ function CalendarApp ({ basePath, className }: Props): React.ReactElement<Props>
}
</div>
</div>
</main>
</StyledMain>
);
}
export default React.memo(styled(CalendarApp)`
const StyledMain = styled.main`
.calendarFlex {
align-items: flex-start;
display: flex;
@ -208,4 +208,6 @@ export default React.memo(styled(CalendarApp)`
}
}
}
`);
`;
export default React.memo(CalendarApp);

View File

@ -197,7 +197,7 @@ function addFiltered (state: EntryInfoTyped[], types: [EntryType, EntryInfo[]][]
}
// TODO council votes, tips closing
function useScheduledImpl (): EntryInfo[] {
function useScheduledImpl (): EntryInfoTyped[] {
const { api } = useApi();
const blockTime = useBlockInterval();
const bestNumber = useBestNumber();

View File

@ -22,9 +22,9 @@ import { getStatement } from './util';
interface Props {
accountId: string;
className?: string;
ethereumAddress: EthereumAddress | null;
ethereumAddress?: EthereumAddress | string | null;
onSuccess?: TxCallback;
statementKind?: StatementKind;
statementKind?: StatementKind | null;
systemChain: string;
}
@ -69,7 +69,7 @@ function Attest ({ accountId, className, ethereumAddress, onSuccess, statementKi
if (noClaim || !statementSentence) {
return (
<Card isError>
<div className={className}>
<StyledDiv className={className}>
{noClaim && (
<p>{t<string>('There is no on-chain claimable balance associated with the Ethereum account {{ethereumAddress}}', {
replace: { ethereumAddress }
@ -80,7 +80,7 @@ function Attest ({ accountId, className, ethereumAddress, onSuccess, statementKi
replace: { ethereumAddress }
})}</p>
)}
</div>
</StyledDiv>
</Card>
);
}
@ -88,7 +88,7 @@ function Attest ({ accountId, className, ethereumAddress, onSuccess, statementKi
if (!accounts.isAccount(accountId)) {
return (
<Card isError>
<div className={className}>
<StyledDiv className={className}>
{t<string>('We found a pre-claim with this Polkadot address. However, attesting requires signing with this account. To continue with attesting, please add this account as an owned account first.')}
<h2>
<FormatBalance
@ -96,14 +96,14 @@ function Attest ({ accountId, className, ethereumAddress, onSuccess, statementKi
value={claimValue}
/>
</h2>
</div>
</StyledDiv>
</Card>
);
}
return (
<Card isSuccess>
<div className={className}>
<StyledDiv className={className}>
<Statement
kind={statementKind}
systemChain={systemChain}
@ -125,9 +125,11 @@ function Attest ({ accountId, className, ethereumAddress, onSuccess, statementKi
tx={api.tx.claims.attest}
/>
</Button.Group>
</div>
</StyledDiv>
</Card>
);
}
export default React.memo(styled(Attest)`${ClaimStyles}`);
const StyledDiv = styled.div`${ClaimStyles}`;
export default React.memo(Attest);

View File

@ -5,7 +5,7 @@ import type { ApiPromise } from '@polkadot/api';
import type { SubmittableExtrinsic } from '@polkadot/api/types';
import type { TxCallback } from '@polkadot/react-components/Status/types';
import type { Option } from '@polkadot/types';
import type { BalanceOf, EthereumAddress, StatementKind } from '@polkadot/types/interfaces';
import type { BalanceOf, EthereumAddress, EthereumSignature, StatementKind } from '@polkadot/types/interfaces';
import type { BN } from '@polkadot/util';
import React, { useEffect, useState } from 'react';
@ -22,12 +22,12 @@ import { addrToChecksum, getStatement } from './util';
interface Props {
accountId: string;
className?: string;
ethereumAddress: EthereumAddress | null;
ethereumSignature: string | null;
ethereumAddress?: EthereumAddress | string | null;
ethereumSignature?: EthereumSignature | string | null;
// Do we sign with `claims.claimAttest` (new) instead of `claims.claim` (old)?
isOldClaimProcess: boolean;
onSuccess?: TxCallback;
statementKind?: StatementKind;
statementKind?: StatementKind | null;
}
interface ConstructTx {
@ -37,7 +37,7 @@ interface ConstructTx {
// Depending on isOldClaimProcess, construct the correct tx.
// FIXME We actually want to return the constructed extrinsic here (probably in useMemo)
function constructTx (api: ApiPromise, systemChain: string, accountId: string, ethereumSignature: string | null, kind: StatementKind | undefined, isOldClaimProcess: boolean): ConstructTx {
function constructTx (api: ApiPromise, systemChain: string, accountId: string, ethereumSignature: EthereumSignature | string | undefined | null, kind: StatementKind | undefined | null, isOldClaimProcess: boolean): ConstructTx {
if (!ethereumSignature) {
return {};
}
@ -84,7 +84,7 @@ function Claim ({ accountId, className = '', ethereumAddress, ethereumSignature,
isError={!hasClaim}
isSuccess={hasClaim}
>
<div className={className}>
<StyledDiv className={className}>
{t<string>('Your Ethereum account')}
<h2>{addrToChecksum(ethereumAddress.toString())}</h2>
{hasClaim
@ -108,7 +108,7 @@ function Claim ({ accountId, className = '', ethereumAddress, ethereumSignature,
{t<string>('does not appear to have a valid claim. Please double check that you have signed the transaction correctly on the correct ETH account.')}
</>
)}
</div>
</StyledDiv>
</Card>
);
}
@ -140,4 +140,6 @@ h2 {
}
`;
export default React.memo(styled(Claim)`${ClaimStyles}`);
const StyledDiv = styled.div`${ClaimStyles}`;
export default React.memo(Claim);

View File

@ -11,7 +11,7 @@ import { getStatement } from './util';
export interface Props {
className?: string;
kind?: StatementKind;
kind?: StatementKind | null;
systemChain: string;
}
@ -40,7 +40,7 @@ function Statement ({ className, kind, systemChain }: Props): React.ReactElement
}
return (
<div className={className}>
<StyledDiv className={className}>
{t('Please read these terms and conditions carefully. By submitting this statement, you are deemed to have accepted these Terms and Conditions. If you do not agree to these terms, please refrain from accessing or proceeding. You can also find them at:')}
<a
className='statementUrl'
@ -54,11 +54,11 @@ function Statement ({ className, kind, systemChain }: Props): React.ReactElement
systemChain={systemChain}
/>
</div>
</div>
</StyledDiv>
);
}
export default React.memo(styled(Statement)`
const StyledDiv = styled.div`
.statement{
border: 1px solid #c2c2c2;
background: #f2f2f2;
@ -82,4 +82,6 @@ export default React.memo(styled(Statement)`
.statementUrl{
margin-left: 0.3rem
}
`);
`;
export default React.memo(Statement);

View File

@ -296,7 +296,7 @@ function ClaimsApp ({ basePath }: Props): React.ReactElement<Props> {
)}
</Columar.Column>
<Columar.Column>
{(step >= Step.Claim) && (
{accountId && (step >= Step.Claim) && (
isPreclaimed
? (
<AttestDisplay