Skip to content

Commit 762d2b0

Browse files
committed
updated to make it mobile compatible
1 parent a71d012 commit 762d2b0

File tree

8 files changed

+212
-29
lines changed

8 files changed

+212
-29
lines changed

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/BatchMetadata.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ function UploadMetadataNFTSection(props: {
135135
const promise = uploadMetadataMutation.mutateAsync(form.getValues());
136136
toast.promise(promise, {
137137
success: "Successfully uploadMetadataed NFT",
138-
error: "Failed to uploadMetadata NFT",
138+
error: (error) => `Failed to uploadMetadata NFT: ${error}`,
139139
});
140140
};
141141

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/Claimable.tsx

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import { isAddress } from "thirdweb";
3232
import { ClaimableERC721, ClaimableERC1155 } from "thirdweb/modules";
3333
import { useActiveAccount, useReadContract } from "thirdweb/react";
3434
import { z } from "zod";
35+
import { CurrencySelector } from "./CurrencySelector";
3536
import { ModuleCardUI, type ModuleCardUIProps } from "./module-card";
3637
import type { ModuleInstanceProps } from "./module-instance";
3738

@@ -227,7 +228,7 @@ export function ClaimableModuleUI(
227228
value="primary-sale-recipient"
228229
className="border-none "
229230
>
230-
<AccordionTrigger className="border-border border-t px-1">
231+
<AccordionTrigger className="border-border border-t px-1 text-left">
231232
Claim Conditions & Primary Sale Recipient
232233
</AccordionTrigger>
233234
<AccordionContent className="px-1">
@@ -331,15 +332,16 @@ function ConfigSection(props: {
331332
toast.promise(promise, {
332333
success:
333334
"Successfully updated claim conditions or primary sale recipient",
334-
error: "Failed to update claim conditions or primary sale recipient",
335+
error: (error) =>
336+
`Failed to update claim conditions or primary sale recipient: ${error}`,
335337
});
336338
};
337339

338340
return (
339341
<Form {...form}>
340342
<form onSubmit={form.handleSubmit(onSubmit)}>
341343
<div className="flex flex-col gap-6">
342-
<div className="flex gap-4">
344+
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
343345
{!props.isErc721 && (
344346
<FormField
345347
control={form.control}
@@ -375,7 +377,7 @@ function ConfigSection(props: {
375377
/>
376378
</div>
377379

378-
<div className="flex gap-4">
380+
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
379381
<FormField
380382
control={form.control}
381383
name="pricePerToken"
@@ -389,27 +391,19 @@ function ConfigSection(props: {
389391
</FormItem>
390392
)}
391393
/>
392-
393394
<FormField
394395
control={form.control}
395396
name="currencyAddress"
396397
render={({ field }) => (
397-
<FormItem className="flex-1">
398+
<FormItem>
398399
<FormLabel>Currency</FormLabel>
399-
<FormControl>
400-
<Input
401-
placeholder="0x..."
402-
{...field}
403-
disabled={!props.isOwnerAccount}
404-
/>
405-
</FormControl>
406-
<FormMessage />
400+
<CurrencySelector field={field} />
407401
</FormItem>
408402
)}
409403
/>
410404
</div>
411405

412-
<div className="flex gap-4">
406+
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
413407
<FormField
414408
control={form.control}
415409
name="maxClaimableSupply"
@@ -447,7 +441,7 @@ function ConfigSection(props: {
447441
control={form.control}
448442
name="startTime"
449443
render={({ field }) => (
450-
<FormItem className="flex flex-1 items-center gap-4">
444+
<FormItem className="flex flex-1 items-center gap-2">
451445
<FormLabel>Start & End Time</FormLabel>
452446
<FormControl>
453447
<DatePickerWithRange
@@ -584,7 +578,7 @@ function MintNFTSection(props: {
584578
const promise = mintMutation.mutateAsync(values);
585579
toast.promise(promise, {
586580
success: "Successfully minted NFT",
587-
error: "Failed to mint NFT",
581+
error: (error) => `Failed to mint NFT: ${error}`,
588582
});
589583
};
590584

@@ -593,7 +587,7 @@ function MintNFTSection(props: {
593587
<form onSubmit={form.handleSubmit(onSubmit)}>
594588
<div className="flex flex-col gap-6">
595589
{/* Other options */}
596-
<div className="flex flex-col gap-4 md:flex-row">
590+
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
597591
<FormField
598592
control={form.control}
599593
name="recipient"
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
import { Button } from "@/components/ui/button";
2+
import { FormControl } from "@/components/ui/form";
3+
import { Input } from "@/components/ui/input";
4+
import {
5+
Select,
6+
SelectContent,
7+
SelectItem,
8+
SelectTrigger,
9+
SelectValue,
10+
} from "@/components/ui/select";
11+
import { CURRENCIES, type CurrencyMetadata } from "constants/currencies";
12+
import { useMemo, useState } from "react";
13+
import type { ControllerRenderProps, FieldValues } from "react-hook-form";
14+
import { NATIVE_TOKEN_ADDRESS, ZERO_ADDRESS, isAddress } from "thirdweb";
15+
import { useAllChainsData } from "../../../../../../../hooks/chains/allChains";
16+
17+
interface CurrencySelectorProps<
18+
TFieldValues extends FieldValues = FieldValues,
19+
> {
20+
small?: boolean;
21+
hideDefaultCurrencies?: boolean;
22+
showCustomCurrency?: boolean;
23+
isPaymentsSelector?: boolean;
24+
defaultCurrencies?: CurrencyMetadata[];
25+
contractChainId: number;
26+
field: ControllerRenderProps<TFieldValues>;
27+
}
28+
29+
export const CurrencySelector: React.FC<CurrencySelectorProps> = ({
30+
small,
31+
hideDefaultCurrencies,
32+
showCustomCurrency = true,
33+
isPaymentsSelector = false,
34+
defaultCurrencies = [],
35+
field,
36+
contractChainId: chainId,
37+
}) => {
38+
const { idToChain } = useAllChainsData();
39+
const chain = chainId ? idToChain.get(chainId) : undefined;
40+
41+
const helperCurrencies =
42+
defaultCurrencies.length > 0
43+
? defaultCurrencies
44+
: chainId
45+
? CURRENCIES[chainId] || []
46+
: [];
47+
48+
const [isAddingCurrency, setIsAddingCurrency] = useState(false);
49+
const [editCustomCurrency, setEditCustomCurrency] = useState("");
50+
const [customCurrency, setCustomCurrency] = useState("");
51+
const [initialValue] = useState(field.value);
52+
53+
const isCustomCurrency: boolean = useMemo(() => {
54+
if (initialValue && chainId && initialValue !== customCurrency) {
55+
if (chainId in CURRENCIES) {
56+
return !CURRENCIES[chainId]?.find(
57+
(currency: CurrencyMetadata) =>
58+
currency.address.toLowerCase() === initialValue.toLowerCase(),
59+
);
60+
}
61+
62+
// for non-default chains
63+
return true;
64+
}
65+
66+
return false;
67+
}, [chainId, customCurrency, initialValue]);
68+
69+
const currencyOptions: CurrencyMetadata[] = [
70+
...(isPaymentsSelector
71+
? []
72+
: [
73+
{
74+
address: NATIVE_TOKEN_ADDRESS.toLowerCase(),
75+
name: chain?.nativeCurrency.name || "Native Token",
76+
symbol: chain?.nativeCurrency.symbol || "",
77+
},
78+
]),
79+
...(hideDefaultCurrencies ? [] : helperCurrencies),
80+
];
81+
82+
const addCustomCurrency = () => {
83+
if (!isAddress(editCustomCurrency)) {
84+
return;
85+
}
86+
if (editCustomCurrency) {
87+
setCustomCurrency(editCustomCurrency);
88+
if (field.onChange) {
89+
field.onChange({
90+
target: { value: editCustomCurrency },
91+
// biome-ignore lint/suspicious/noExplicitAny: FIXME
92+
} as any);
93+
}
94+
} else {
95+
setEditCustomCurrency(customCurrency);
96+
}
97+
98+
setIsAddingCurrency(false);
99+
setEditCustomCurrency("");
100+
};
101+
102+
if (isAddingCurrency && !hideDefaultCurrencies) {
103+
return (
104+
<div className="flex items-center">
105+
<Button
106+
className="rounded-r-none rounded-l-lg"
107+
onClick={() => setIsAddingCurrency(false)}
108+
>
109+
&lt;-
110+
</Button>
111+
<Input
112+
{...field}
113+
className="w-full rounded-none"
114+
required
115+
placeholder="ERC20 Address"
116+
value={editCustomCurrency}
117+
onChange={(e) => setEditCustomCurrency(e.target.value)}
118+
/>
119+
<Button
120+
className="rounded-r-lg rounded-l-none"
121+
onClick={addCustomCurrency}
122+
disabled={!isAddress(editCustomCurrency)}
123+
>
124+
Save
125+
</Button>
126+
</div>
127+
);
128+
}
129+
130+
return (
131+
<div
132+
className={`flex flex-col ${small && !hideDefaultCurrencies ? "mt-1" : "mt-0"}`}
133+
>
134+
<Select
135+
onValueChange={(value) =>
136+
value === "custom" ? setIsAddingCurrency(true) : field.onChange(value)
137+
}
138+
value={
139+
isPaymentsSelector
140+
? field.value
141+
: field.value?.toLowerCase() === ZERO_ADDRESS.toLowerCase()
142+
? NATIVE_TOKEN_ADDRESS.toLowerCase()
143+
: field.value?.toLowerCase()
144+
}
145+
>
146+
<FormControl>
147+
<SelectTrigger>
148+
<SelectValue placeholder="Select Currency" />
149+
</SelectTrigger>
150+
</FormControl>
151+
<SelectContent>
152+
{chainId &&
153+
!hideDefaultCurrencies &&
154+
currencyOptions.map((currency: CurrencyMetadata, idx: number) => (
155+
<SelectItem
156+
key={`${currency.address}-${idx}`}
157+
value={
158+
isPaymentsSelector
159+
? currency.symbol
160+
: currency.address.toLowerCase()
161+
}
162+
>
163+
{currency.symbol} ({currency.name})
164+
</SelectItem>
165+
))}
166+
{isCustomCurrency &&
167+
!isPaymentsSelector &&
168+
initialValue !== NATIVE_TOKEN_ADDRESS.toLowerCase() && (
169+
<SelectItem key={initialValue} value={initialValue}>
170+
{initialValue}
171+
</SelectItem>
172+
)}
173+
{customCurrency && (
174+
<SelectItem
175+
key={customCurrency}
176+
value={customCurrency.toLowerCase()}
177+
>
178+
{customCurrency}
179+
</SelectItem>
180+
)}
181+
{!hideDefaultCurrencies && showCustomCurrency && (
182+
<SelectItem value="custom">Custom ERC20</SelectItem>
183+
)}
184+
</SelectContent>
185+
</Select>
186+
</div>
187+
);
188+
};

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/Mintable.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ function PrimarySalesSection(props: {
249249
const promise = updateMutation.mutateAsync(form.getValues());
250250
toast.promise(promise, {
251251
success: "Successfully updated primary sale recipient",
252-
error: "Failed to update primary sale recipient",
252+
error: (error) => `Failed to update primary sale recipient: ${error}`,
253253
});
254254
};
255255

@@ -320,7 +320,7 @@ function MintNFTSection(props: {
320320
const promise = mintMutation.mutateAsync(form.getValues());
321321
toast.promise(promise, {
322322
success: "Successfully minted NFT",
323-
error: "Failed to mint NFT",
323+
error: (error) => `Failed to mint NFT: ${error}`,
324324
});
325325
};
326326

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/OpenEditionMetadata.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ function SetSharedMetadataSection(props: {
132132
const promise = setSharedMetadataMutation.mutateAsync(form.getValues());
133133
toast.promise(promise, {
134134
success: "Successfully set shared metadata",
135-
error: "Failed to set shared metadata",
135+
error: (error) => `Failed to set shared metadata: ${error}`,
136136
});
137137
};
138138

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/Royalty.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ function RoyaltyInfoPerTokenSection(props: {
232232
);
233233
toast.promise(promise, {
234234
success: "Successfully set royalty info for token",
235-
error: "Failed to set royalty info for token",
235+
error: (error) => `Failed to set royalty info for token: ${error}`,
236236
});
237237
};
238238

@@ -242,7 +242,7 @@ function RoyaltyInfoPerTokenSection(props: {
242242
<div className="flex flex-col gap-4">
243243
<div className="h-1" />
244244

245-
<div className="flex gap-4">
245+
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
246246
<FormField
247247
control={form.control}
248248
name="tokenId"
@@ -361,7 +361,8 @@ function DefaultRoyaltyInfoSection(props: {
361361
const promise = updateMutation.mutateAsync(form.getValues());
362362
toast.promise(promise, {
363363
success: "Successfully updated royalty info or transfer validator",
364-
error: "Failed to update royalty info or transfer validator",
364+
error: (error) =>
365+
`Failed to update royalty info or transfer validator: ${error}`,
365366
});
366367
};
367368

@@ -371,7 +372,7 @@ function DefaultRoyaltyInfoSection(props: {
371372
<div className="flex flex-col gap-4">
372373
<div className="h-1" />
373374

374-
<div className="flex gap-4">
375+
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
375376
<FormField
376377
control={form.control}
377378
name="recipient"

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/Transferable.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ export function TransferableModuleUI(
149149
const promise = updateMutation.mutateAsync(values);
150150
toast.promise(promise, {
151151
success: "Successfully updated transfer restrictions",
152-
error: "Failed to update transfer restrictions",
152+
error: (error) => `Failed to update transfer restrictions: ${error}`,
153153
});
154154
};
155155

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/nft/PropertiesFormControl.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export function PropertiesFormControl<
6969
render={({ field }) => (
7070
<FormItem className="grow">
7171
<FormControl>
72-
<Input placeholder="0x..." {...field} />
72+
<Input {...field} />
7373
</FormControl>
7474
<FormMessage />
7575
</FormItem>
@@ -82,7 +82,7 @@ export function PropertiesFormControl<
8282
render={({ field }) => (
8383
<FormItem className="grow">
8484
<FormControl>
85-
<Input placeholder="0x..." {...field} />
85+
<Input {...field} />
8686
</FormControl>
8787
<FormMessage />
8888
</FormItem>

0 commit comments

Comments
 (0)