Skip to content

Commit b371bf9

Browse files
committed
Dashboard: Published Contract page UI improvements, Fix audit link (#7735)
<!-- ## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes" If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000): ## Notes for the reviewer Anything important to call out? Be sure to also clarify these in your comments. ## How to test Unit tests, playground, etc. --> <!-- start pr-codex --> --- ## PR-Codex overview This PR focuses on improving the handling of IPFS URLs, enhancing the user interface, and refactoring components for better readability and maintainability. It includes updates to various components and functions to streamline the codebase and improve functionality. ### Detailed summary - Changed `shortenString` default parameter from `true` to `false`. - Updated `SelectTrigger` to have a `w-fit` class. - Replaced `replaceIpfsUrl` with `publicIPFSGateway` and `resolveSchemeWithErrorHandler` in multiple components. - Modified `ContractFunctionsOverview` to remove `onlyFunctions` prop. - Updated UI elements for consistency and better spacing. - Refactored `PublisherHeader` to `PublisherLink` for clarity. - Enhanced `PublishedContract` component layout and structure. - Added account address handling in multiple components. - Improved error handling and logging in IPFS URL resolution. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added an "Edit" button to contract headers, visible only to the publisher when viewing their own contract. * Publisher information is now displayed with a more compact and streamlined UI. * **UI Improvements** * Enhanced styling for contract headings, buttons, and function panels for better readability and consistency. * Updated publisher and contract layouts for improved clarity and usability. * Improved tab logic and feedback in contract function panels, including clearer "No inputs required" messaging. * Adjusted layout widths and border styles for published contract pages. * Refined link styling and layout in platform fee information sections. * Modified version selector width behavior for better fit. * **Bug Fixes** * Updated IPFS URL handling for images and links, ensuring more reliable and consistent resolution. * **Refactor** * Simplified and consolidated publisher and contract components for maintainability. * Replaced or removed deprecated utility functions for URL resolution. * Streamlined function panel logic and removed unnecessary props. * Refactored publisher header component to a more compact link-based design. * **Chores** * Updated internal utility defaults (e.g., string shortening behavior) to improve display consistency. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent cf401be commit b371bf9

File tree

18 files changed

+307
-324
lines changed

18 files changed

+307
-324
lines changed

apps/dashboard/src/@/components/blocks/TokenSelector.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ import { SelectWithSearch } from "@/components/blocks/select-with-search";
1111
import { Badge } from "@/components/ui/badge";
1212
import { useAllChainsData } from "@/hooks/chains/allChains";
1313
import { useTokensData } from "@/hooks/tokens";
14-
import { replaceIpfsUrl } from "@/lib/sdk";
1514
import { cn } from "@/lib/utils";
1615
import { fallbackChainIcon } from "@/utils/chain-icons";
16+
import { resolveSchemeWithErrorHandler } from "@/utils/resolveSchemeWithErrorHandler";
1717
import { Spinner } from "../ui/Spinner/Spinner";
1818

1919
type Option = { label: string; value: string };
@@ -122,7 +122,10 @@ export function TokenSelector(props: {
122122
return option.label;
123123
}
124124
const resolvedSrc = token.iconUri
125-
? replaceIpfsUrl(token.iconUri, props.client)
125+
? resolveSchemeWithErrorHandler({
126+
client: props.client,
127+
uri: token.iconUri,
128+
})
126129
: fallbackChainIcon;
127130

128131
return (

apps/dashboard/src/@/components/contract-components/contract-deploy-form/platform-fee-fieldset.tsx

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import Link from "next/link";
21
import type { ThirdwebClient } from "thirdweb";
32
import { BasisPointsInput } from "@/components/blocks/BasisPointsInput";
43
import { FormFieldSetup } from "@/components/blocks/FormFieldSetup";
54
import { SolidityInput } from "@/components/solidity-inputs";
5+
import { UnderlineLink } from "@/components/ui/UnderlineLink";
66
import { Fieldset } from "./common";
77
import type { CustomContractDeploymentForm } from "./custom-contract";
88

@@ -78,30 +78,28 @@ export const PlatformFeeFieldset: React.FC<PlatformFeeFieldsetProps> = ({
7878
</FormFieldSetup>
7979
</>
8080
) : isMarketplace ? (
81-
<p className="mb-3 pt-4 text-muted-foreground text-sm italic">
81+
<p className="text-muted-foreground text-sm leading-relaxed">
8282
A 2.5% platform fee is deducted from each sale to support ongoing
83-
platform operations and improvements.{" "}
84-
<Link
85-
className="text-blue-500 underline"
83+
platform operations and improvements. <br />
84+
<UnderlineLink
8685
href={"https://thirdweb.com/pricing"}
8786
rel="noopener noreferrer"
8887
target="_blank"
8988
>
9089
See fee breakdown on pricing page.
91-
</Link>
90+
</UnderlineLink>
9291
</p>
9392
) : (
94-
<p className="mb-3 pt-4 text-muted-foreground text-sm italic">
93+
<p className="text-muted-foreground text-sm leading-relaxed">
9594
A 2.5% platform fee is deducted from each primary sale price to
96-
support ongoing platform operations and improvements.{" "}
97-
<Link
98-
className="text-blue-500 underline"
95+
support ongoing platform operations and improvements. <br />
96+
<UnderlineLink
9997
href={"https://thirdweb.com/pricing"}
10098
rel="noopener noreferrer"
10199
target="_blank"
102100
>
103101
See fee breakdown on pricing page.
104-
</Link>
102+
</UnderlineLink>
105103
</p>
106104
)}
107105
</div>
Lines changed: 56 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
"use client";
22

3-
import { ExternalLinkIcon } from "lucide-react";
3+
import { Edit3Icon } from "lucide-react";
44
import Link from "next/link";
55
import { type ThirdwebClient, ZERO_ADDRESS } from "thirdweb";
66
import {
77
AccountAddress,
88
AccountAvatar,
9-
AccountBlobbie,
109
AccountName,
1110
AccountProvider,
1211
} from "thirdweb/react";
@@ -15,77 +14,69 @@ import { useEns } from "@/hooks/contract-hooks";
1514
import { replaceDeployerAddress } from "@/lib/publisher-utils";
1615
import { shortenIfAddress } from "@/utils/usedapp-external";
1716

18-
interface PublisherHeaderProps {
19-
wallet: string;
20-
client: ThirdwebClient;
21-
}
22-
export const PublisherHeader: React.FC<PublisherHeaderProps> = ({
17+
export function PublisherLink({
2318
wallet,
2419
client,
25-
}) => {
20+
}: {
21+
wallet: string;
22+
client: ThirdwebClient;
23+
}) {
2624
const ensQuery = useEns({
2725
addressOrEnsName: wallet,
2826
client,
2927
});
3028

3129
return (
32-
<div>
33-
<h4 className="font-medium text-base mb-3">Published by</h4>
34-
<AccountProvider
35-
// passing zero address during loading time to prevent the component from crashing
36-
address={ensQuery.data?.address || ZERO_ADDRESS}
37-
client={client}
38-
>
39-
<div className="flex items-center gap-3 relative">
40-
<div className="translate-y-0.5">
41-
<AccountAvatar
42-
className="size-[34px] rounded-full border border-border border-solid object-cover"
43-
fallbackComponent={
44-
<AccountBlobbie className="size-[34px] rounded-full" />
45-
}
46-
loadingComponent={
47-
<Skeleton className="size-[34px] rounded-full" />
48-
}
49-
/>
50-
</div>
51-
52-
<div className="space-y-1">
53-
<Link
54-
className="hover:underline leading-none before:absolute before:inset-0"
55-
href={replaceDeployerAddress(
56-
`/${ensQuery.data?.ensName || wallet}`,
57-
)}
58-
rel="noopener noreferrer"
59-
target="_blank"
60-
>
61-
<AccountName
62-
className="text-base leading-none font-medium"
63-
fallbackComponent={
64-
// When social profile API support other TLDs as well - we can remove this condition
65-
ensQuery.data?.ensName ? (
66-
<span className="text-base leading-none font-medium">
67-
{ensQuery.data?.ensName}
68-
</span>
69-
) : (
70-
<AccountAddress
71-
formatFn={(addr) =>
72-
shortenIfAddress(replaceDeployerAddress(addr))
73-
}
74-
/>
75-
)
76-
}
77-
formatFn={(name) => replaceDeployerAddress(name)}
78-
loadingComponent={<Skeleton className="h-6 w-40" />}
79-
/>
80-
</Link>
30+
<AccountProvider
31+
// passing zero address during loading time to prevent the component from crashing
32+
address={ensQuery.data?.address || ZERO_ADDRESS}
33+
client={client}
34+
>
35+
<div className="flex items-center gap-2.5 relative">
36+
<div>
37+
<AccountAvatar
38+
className="size-[34px] rounded-full border border-border border-solid object-cover"
39+
fallbackComponent={
40+
<div className="size-[34px] rounded-full flex items-center justify-center border bg-card">
41+
<Edit3Icon className="size-3.5 text-muted-foreground" />
42+
</div>
43+
}
44+
loadingComponent={<Skeleton className="size-[34px] rounded-full" />}
45+
/>
46+
</div>
8147

82-
<span className="text-sm text-muted-foreground flex items-center gap-1.5 leading-none">
83-
View all published contracts{" "}
84-
<ExternalLinkIcon className="size-3 text-muted-foreground" />
85-
</span>
48+
<Link
49+
className="hover:underline before:absolute before:inset-0 space-y-1.5"
50+
href={replaceDeployerAddress(`/${ensQuery.data?.ensName || wallet}`)}
51+
rel="noopener noreferrer"
52+
target="_blank"
53+
>
54+
<div className="text-sm font-medium text-foreground leading-none">
55+
Published by
8656
</div>
87-
</div>
88-
</AccountProvider>
89-
</div>
57+
58+
<AccountName
59+
className="text-sm text-foreground leading-none"
60+
fallbackComponent={
61+
// When social profile API support other TLDs as well - we can remove this condition
62+
ensQuery.data?.ensName ? (
63+
<span className="text-sm text-muted-foreground leading-none">
64+
{ensQuery.data?.ensName}
65+
</span>
66+
) : (
67+
<AccountAddress
68+
className="text-sm text-muted-foreground leading-none"
69+
formatFn={(addr) =>
70+
shortenIfAddress(replaceDeployerAddress(addr))
71+
}
72+
/>
73+
)
74+
}
75+
formatFn={(name) => replaceDeployerAddress(name)}
76+
loadingComponent={<Skeleton className="h-[17px] w-40" />}
77+
/>
78+
</Link>
79+
</div>
80+
</AccountProvider>
9081
);
91-
};
82+
}

apps/dashboard/src/@/components/contract-components/shared/contract-id-image.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import Image from "next/image";
55
import type { FetchDeployMetadataResult } from "thirdweb/contract";
66
import { DASHBOARD_THIRDWEB_SECRET_KEY } from "@/constants/server-envs";
77
import { getConfiguredThirdwebClient } from "@/constants/thirdweb.server";
8-
import { replaceIpfsUrl } from "@/lib/sdk";
8+
import { resolveSchemeWithErrorHandler } from "@/utils/resolveSchemeWithErrorHandler";
99
import generalContractIcon from "../../../../../public/assets/tw-icons/general.png";
1010

1111
type ContractIdImageProps = {
@@ -29,13 +29,13 @@ export const ContractIdImage: React.FC<ContractIdImageProps> = ({
2929
className="size-8 rounded-full"
3030
src={
3131
DASHBOARD_THIRDWEB_SECRET_KEY
32-
? replaceIpfsUrl(
33-
logo,
34-
getConfiguredThirdwebClient({
32+
? resolveSchemeWithErrorHandler({
33+
client: getConfiguredThirdwebClient({
3534
secretKey: DASHBOARD_THIRDWEB_SECRET_KEY,
3635
teamId: undefined,
3736
}),
38-
)
37+
uri: logo,
38+
})
3939
: logo
4040
}
4141
/>

apps/dashboard/src/@/components/contracts/code-overview.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,7 @@ export function CodeOverview(props: {
657657

658658
<div className="flex flex-col gap-4">
659659
<div className="space-y-2">
660-
<h2 className="text-lg font-semibold tracking-tight">
660+
<h2 className="text-2xl font-semibold tracking-tight">
661661
{isAccountFactory
662662
? "Direct contract interaction (advanced)"
663663
: chainInfo
@@ -851,7 +851,7 @@ function AccentButton(props: {
851851
return (
852852
<Button
853853
className={cn(
854-
"text-sm justify-start h-auto py-1 px-2 text-muted-foreground",
854+
"text-sm justify-start h-auto py-1.5 px-2 text-muted-foreground font-normal font-mono",
855855
props.isActive && "text-foreground bg-accent",
856856
)}
857857
onClick={props.onClick}

0 commit comments

Comments
 (0)