Skip to content

Commit b41693c

Browse files
committed
refactor: extract AccountCard component with raw data toggle
1 parent 7834e64 commit b41693c

20 files changed

+1273
-1100
lines changed

app/components/account/CompressedNftCard.tsx

Lines changed: 44 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { AccountCard } from '@features/account';
12
import { Account } from '@providers/accounts';
23
import { PublicKey } from '@solana/web3.js';
34
import { createRef, Suspense } from 'react';
@@ -12,7 +13,6 @@ import { Address } from '../common/Address';
1213
import { InfoTooltip } from '../common/InfoTooltip';
1314
import { LoadingArtPlaceholder } from '../common/LoadingArtPlaceholder';
1415
import { ArtContent } from '../common/NFTArt';
15-
import { TableCardBody } from '../common/TableCardBody';
1616
import { getCreatorDropdownItems, getIsMutablePill, getVerifiedCollectionPill } from './MetaplexNFTHeader';
1717
import { UnknownAccountCard } from './UnknownAccountCard';
1818

@@ -25,54 +25,49 @@ export function CompressedNftCard({ account }: { account: Account }) {
2525
const updateAuthority = compressedNft.authorities.find(authority => authority.scopes.includes('full'))?.address;
2626

2727
return (
28-
<div className="card">
29-
<div className="card-header">
30-
<h3 className="card-header-title mb-0 d-flex align-items-center">Overview</h3>
31-
</div>
32-
<TableCardBody>
33-
<tr>
34-
<td>Address</td>
35-
<td className="text-lg-end">
36-
<Address pubkey={account.pubkey} alignRight raw />
37-
</td>
38-
</tr>
39-
<tr>
40-
<td>Owner</td>
41-
<td className="text-lg-end">
42-
<Address pubkey={new PublicKey(compressedNft.ownership.owner)} alignRight link />
43-
</td>
44-
</tr>
45-
<tr>
46-
<td>Verified Collection Address</td>
47-
<td className="text-lg-end">
48-
{collectionGroup ? (
49-
<Address pubkey={new PublicKey(collectionGroup.group_value)} alignRight link />
50-
) : (
51-
'None'
52-
)}
53-
</td>
54-
</tr>
55-
<tr>
56-
<td>Update Authority</td>
57-
<td className="text-lg-end">
58-
{updateAuthority ? <Address pubkey={new PublicKey(updateAuthority)} alignRight link /> : 'None'}
59-
</td>
60-
</tr>
61-
<tr>
62-
<td>Website</td>
63-
<td className="text-lg-end">
64-
<a rel="noopener noreferrer" target="_blank" href={compressedNft.content.links.external_url}>
65-
{compressedNft.content.links.external_url}
66-
<ExternalLink className="align-text-top ms-2" size={13} />
67-
</a>
68-
</td>
69-
</tr>
70-
<tr>
71-
<td>Seller Fee</td>
72-
<td className="text-lg-end">{`${compressedNft.royalty.basis_points / 100}%`}</td>
73-
</tr>
74-
</TableCardBody>
75-
</div>
28+
<AccountCard title="Overview" account={account}>
29+
<tr>
30+
<td>Address</td>
31+
<td className="text-lg-end">
32+
<Address pubkey={account.pubkey} alignRight raw />
33+
</td>
34+
</tr>
35+
<tr>
36+
<td>Owner</td>
37+
<td className="text-lg-end">
38+
<Address pubkey={new PublicKey(compressedNft.ownership.owner)} alignRight link />
39+
</td>
40+
</tr>
41+
<tr>
42+
<td>Verified Collection Address</td>
43+
<td className="text-lg-end">
44+
{collectionGroup ? (
45+
<Address pubkey={new PublicKey(collectionGroup.group_value)} alignRight link />
46+
) : (
47+
'None'
48+
)}
49+
</td>
50+
</tr>
51+
<tr>
52+
<td>Update Authority</td>
53+
<td className="text-lg-end">
54+
{updateAuthority ? <Address pubkey={new PublicKey(updateAuthority)} alignRight link /> : 'None'}
55+
</td>
56+
</tr>
57+
<tr>
58+
<td>Website</td>
59+
<td className="text-lg-end">
60+
<a rel="noopener noreferrer" target="_blank" href={compressedNft.content.links.external_url}>
61+
{compressedNft.content.links.external_url}
62+
<ExternalLink className="align-text-top ms-2" size={13} />
63+
</a>
64+
</td>
65+
</tr>
66+
<tr>
67+
<td>Seller Fee</td>
68+
<td className="text-lg-end">{`${compressedNft.royalty.basis_points / 100}%`}</td>
69+
</tr>
70+
</AccountCard>
7671
);
7772
}
7873

Lines changed: 56 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { AccountAddressRow, AccountBalanceRow, AccountHeader } from '@components/common/Account';
1+
import { AccountAddressRow, AccountBalanceRow } from '@components/common/Account';
22
import { Address } from '@components/common/Address';
3-
import { TableCardBody } from '@components/common/TableCardBody';
3+
import { AccountCard } from '@features/account';
44
import { Account, useFetchAccountInfo } from '@providers/accounts';
55
import { PublicKey } from '@solana/web3.js';
66
import { ConfigAccount, StakeConfigInfoAccount, ValidatorInfoAccount } from '@validators/accounts/config';
@@ -31,78 +31,70 @@ function StakeConfigCard({ account, configAccount }: { account: Account; configA
3131
}).format(configAccount.info.slashPenalty / MAX_SLASH_PENALTY);
3232

3333
return (
34-
<div className="card">
35-
<AccountHeader title="Stake Config" refresh={() => refresh(account.pubkey, 'parsed')} />
36-
37-
<TableCardBody>
38-
<AccountAddressRow account={account} />
39-
<AccountBalanceRow account={account} />
40-
41-
<tr>
42-
<td>Warmup / Cooldown Rate</td>
43-
<td className="text-lg-end">{warmupCooldownFormatted}</td>
44-
</tr>
45-
46-
<tr>
47-
<td>Slash Penalty</td>
48-
<td className="text-lg-end">{slashPenaltyFormatted}</td>
49-
</tr>
50-
</TableCardBody>
51-
</div>
34+
<AccountCard title="Stake Config" account={account} refresh={() => refresh(account.pubkey, 'parsed')}>
35+
<AccountAddressRow account={account} />
36+
<AccountBalanceRow account={account} />
37+
38+
<tr>
39+
<td>Warmup / Cooldown Rate</td>
40+
<td className="text-lg-end">{warmupCooldownFormatted}</td>
41+
</tr>
42+
43+
<tr>
44+
<td>Slash Penalty</td>
45+
<td className="text-lg-end">{slashPenaltyFormatted}</td>
46+
</tr>
47+
</AccountCard>
5248
);
5349
}
5450

5551
function ValidatorInfoCard({ account, configAccount }: { account: Account; configAccount: ValidatorInfoAccount }) {
5652
const refresh = useFetchAccountInfo();
5753
return (
58-
<div className="card">
59-
<AccountHeader title="Validator Info" refresh={() => refresh(account.pubkey, 'parsed')} />
54+
<AccountCard title="Validator Info" account={account} refresh={() => refresh(account.pubkey, 'parsed')}>
55+
<AccountAddressRow account={account} />
56+
<AccountBalanceRow account={account} />
6057

61-
<TableCardBody>
62-
<AccountAddressRow account={account} />
63-
<AccountBalanceRow account={account} />
64-
65-
{configAccount.info.configData.name && (
66-
<tr>
67-
<td>Name</td>
68-
<td className="text-lg-end">{configAccount.info.configData.name}</td>
69-
</tr>
70-
)}
58+
{configAccount.info.configData.name && (
59+
<tr>
60+
<td>Name</td>
61+
<td className="text-lg-end">{configAccount.info.configData.name}</td>
62+
</tr>
63+
)}
7164

72-
{configAccount.info.configData.keybaseUsername && (
73-
<tr>
74-
<td>Keybase Username</td>
75-
<td className="text-lg-end">{configAccount.info.configData.keybaseUsername}</td>
76-
</tr>
77-
)}
65+
{configAccount.info.configData.keybaseUsername && (
66+
<tr>
67+
<td>Keybase Username</td>
68+
<td className="text-lg-end">{configAccount.info.configData.keybaseUsername}</td>
69+
</tr>
70+
)}
7871

79-
{configAccount.info.configData.website && (
80-
<tr>
81-
<td>Website</td>
82-
<td className="text-lg-end">
83-
<a href={configAccount.info.configData.website} target="_blank" rel="noopener noreferrer">
84-
{configAccount.info.configData.website}
85-
</a>
86-
</td>
87-
</tr>
88-
)}
72+
{configAccount.info.configData.website && (
73+
<tr>
74+
<td>Website</td>
75+
<td className="text-lg-end">
76+
<a href={configAccount.info.configData.website} target="_blank" rel="noopener noreferrer">
77+
{configAccount.info.configData.website}
78+
</a>
79+
</td>
80+
</tr>
81+
)}
8982

90-
{configAccount.info.configData.details && (
91-
<tr>
92-
<td>Details</td>
93-
<td className="text-lg-end">{configAccount.info.configData.details}</td>
94-
</tr>
95-
)}
83+
{configAccount.info.configData.details && (
84+
<tr>
85+
<td>Details</td>
86+
<td className="text-lg-end">{configAccount.info.configData.details}</td>
87+
</tr>
88+
)}
9689

97-
{configAccount.info.keys && configAccount.info.keys.length > 1 && (
98-
<tr>
99-
<td>Signer</td>
100-
<td className="text-lg-end">
101-
<Address pubkey={new PublicKey(configAccount.info.keys[1].pubkey)} link alignRight />
102-
</td>
103-
</tr>
104-
)}
105-
</TableCardBody>
106-
</div>
90+
{configAccount.info.keys && configAccount.info.keys.length > 1 && (
91+
<tr>
92+
<td>Signer</td>
93+
<td className="text-lg-end">
94+
<Address pubkey={new PublicKey(configAccount.info.keys[1].pubkey)} link alignRight />
95+
</td>
96+
</tr>
97+
)}
98+
</AccountCard>
10799
);
108100
}

app/components/account/FeatureAccountSection.tsx

Lines changed: 52 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Address } from '@components/common/Address';
22
import { Slot } from '@components/common/Slot';
3-
import { TableCardBody } from '@components/common/TableCardBody';
3+
import { AccountCard } from '@features/account';
44
import { Account } from '@providers/accounts';
55
import { PublicKey } from '@solana/web3.js';
66
import { parseFeatureAccount, useFeatureAccount } from '@utils/parseFeatureAccount';
@@ -33,7 +33,12 @@ export function FeatureAccountSection({ account }: { account: Account }) {
3333
<FeatureCard account={account} />
3434
) : (
3535
// feature that is preset at JSON would not have data about slot. leave it as null
36-
<BaseFeatureCard activatedAt={null} address={address} featureInfo={maybeFeatureInfo} />
36+
<BaseFeatureCard
37+
account={account}
38+
activatedAt={null}
39+
address={address}
40+
featureInfo={maybeFeatureInfo}
41+
/>
3742
)}
3843
</ErrorBoundary>
3944
);
@@ -47,14 +52,22 @@ const FeatureCard = ({ account }: Props) => {
4752
const feature = parseFeatureAccount(account);
4853
const featureInfo = useMemo(() => getFeatureInfo(feature.address), [feature.address]);
4954

50-
return <BaseFeatureCard address={feature.address} activatedAt={feature.activatedAt} featureInfo={featureInfo} />;
55+
return (
56+
<BaseFeatureCard
57+
account={account}
58+
address={feature.address}
59+
activatedAt={feature.activatedAt}
60+
featureInfo={featureInfo}
61+
/>
62+
);
5163
};
5264

5365
const BaseFeatureCard = ({
66+
account,
5467
activatedAt,
5568
address,
5669
featureInfo,
57-
}: ReturnType<typeof parseFeatureAccount> & { featureInfo?: FeatureInfoType }) => {
70+
}: ReturnType<typeof parseFeatureAccount> & { account: Account; featureInfo?: FeatureInfoType }) => {
5871
const { cluster, clusterInfo } = useCluster();
5972

6073
let activatedAtSlot;
@@ -96,55 +109,47 @@ const BaseFeatureCard = ({
96109
}
97110

98111
return (
99-
<div className="card">
100-
<div className="card-header">
101-
<h3 className="card-header-title mb-0 d-flex align-items-center">
102-
{featureInfo?.title ?? 'Feature Activation'}
103-
</h3>
104-
</div>
105-
106-
<TableCardBody layout="expanded">
107-
<tr>
108-
<td>Address</td>
109-
<td>
110-
<Address pubkey={new PublicKey(address)} alignRight raw />
111-
</td>
112-
</tr>
112+
<AccountCard title={featureInfo?.title ?? 'Feature Activation'} account={account} layout="expanded">
113+
<tr>
114+
<td>Address</td>
115+
<td>
116+
<Address pubkey={new PublicKey(address)} alignRight raw />
117+
</td>
118+
</tr>
113119

114-
<tr>
115-
<td className="text-nowrap">Activated?</td>
116-
<td className="text-lg-end">
117-
{activatedAt !== null ? (
118-
<span className="badge bg-success">Active on {clusterName(cluster)}</span>
119-
) : (
120-
<code>Not yet activated on {clusterName(cluster)}</code>
121-
)}
122-
</td>
123-
</tr>
120+
<tr>
121+
<td className="text-nowrap">Activated?</td>
122+
<td className="text-lg-end">
123+
{activatedAt !== null ? (
124+
<span className="badge bg-success">Active on {clusterName(cluster)}</span>
125+
) : (
126+
<code>Not yet activated on {clusterName(cluster)}</code>
127+
)}
128+
</td>
129+
</tr>
124130

125-
{activatedAtSlot}
131+
{activatedAtSlot}
132+
133+
<tr>
134+
<td className="text-nowrap">Cluster Activation</td>
135+
<td className="text-lg-end">
136+
<ClusterActivationEpochAtCluster
137+
cluster={cluster}
138+
clusterInfo={clusterInfo}
139+
activatedAt={activatedAt}
140+
/>
141+
</td>
142+
</tr>
126143

144+
{featureInfo?.description && (
127145
<tr>
128-
<td className="text-nowrap">Cluster Activation</td>
129-
<td className="text-lg-end">
130-
<ClusterActivationEpochAtCluster
131-
cluster={cluster}
132-
clusterInfo={clusterInfo}
133-
activatedAt={activatedAt}
134-
/>
135-
</td>
146+
<td>Description</td>
147+
<td className="text-lg-end">{featureInfo?.description}</td>
136148
</tr>
149+
)}
137150

138-
{featureInfo?.description && (
139-
<tr>
140-
<td>Description</td>
141-
<td className="text-lg-end">{featureInfo?.description}</td>
142-
</tr>
143-
)}
144-
145-
{simdLink}
146-
</TableCardBody>
147-
</div>
151+
{simdLink}
152+
</AccountCard>
148153
);
149154
};
150155

0 commit comments

Comments
 (0)