Skip to content

Commit cd9bb1b

Browse files
committed
temp
1 parent 6378f37 commit cd9bb1b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+3154
-663
lines changed

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,17 @@ export function TokenSelector(props: {
159159
? `${props.selectedToken.chainId}:${props.selectedToken.address}`
160160
: undefined;
161161

162+
// if selected value is not in options, add it
163+
if (
164+
selectedValue &&
165+
!options.find((option) => option.value === selectedValue)
166+
) {
167+
options.push({
168+
label: props.selectedToken?.address || "Unknown",
169+
value: selectedValue,
170+
});
171+
}
172+
162173
return (
163174
<SelectWithSearch
164175
searchPlaceholder="Search by name or symbol"
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import type { Meta, StoryObj } from "@storybook/react";
2+
import { DropZone } from "./drop-zone";
3+
4+
const meta = {
5+
title: "blocks/DropZone",
6+
component: DropZone,
7+
decorators: [
8+
(Story) => (
9+
<div className="container max-w-6xl py-10">
10+
<Story />
11+
</div>
12+
),
13+
],
14+
} satisfies Meta<typeof DropZone>;
15+
16+
export default meta;
17+
type Story = StoryObj<typeof meta>;
18+
19+
export const Default: Story = {
20+
args: {
21+
isError: false,
22+
onDrop: () => {},
23+
title: "This is a title",
24+
description: "This is a description for drop zone",
25+
accept: undefined,
26+
resetButton: undefined,
27+
},
28+
};
29+
30+
export const ErrorState: Story = {
31+
args: {
32+
isError: true,
33+
onDrop: () => {},
34+
title: "this is title",
35+
description: "This is a description",
36+
accept: undefined,
37+
resetButton: undefined,
38+
},
39+
};
40+
41+
export const ErrorStateWithResetButton: Story = {
42+
args: {
43+
isError: true,
44+
onDrop: () => {},
45+
title: "this is title",
46+
description: "This is a description",
47+
accept: undefined,
48+
resetButton: {
49+
label: "Remove Files",
50+
onClick: () => {},
51+
},
52+
},
53+
};
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { Button } from "@/components/ui/button";
2+
import { cn } from "@/lib/utils";
3+
import { UploadIcon, XIcon } from "lucide-react";
4+
import { useDropzone } from "react-dropzone";
5+
6+
export function DropZone(props: {
7+
isError: boolean;
8+
onDrop: (acceptedFiles: File[]) => void;
9+
title: string;
10+
description: string;
11+
resetButton:
12+
| {
13+
label: string;
14+
onClick: () => void;
15+
}
16+
| undefined;
17+
className?: string;
18+
accept: string | undefined;
19+
}) {
20+
const { getRootProps, getInputProps } = useDropzone({
21+
onDrop: props.onDrop,
22+
});
23+
24+
const { resetButton } = props;
25+
26+
return (
27+
<div
28+
className={cn(
29+
"flex cursor-pointer items-center justify-center rounded-md border border-dashed bg-card py-10 hover:border-active-border",
30+
props.isError &&
31+
"border-red-500 bg-red-200/30 text-red-500 hover:border-red-600 dark:border-red-900 dark:bg-red-900/30 dark:hover:border-red-800",
32+
props.className,
33+
)}
34+
{...getRootProps()}
35+
>
36+
<input {...getInputProps()} accept={props.accept} />
37+
<div className="flex flex-col items-center justify-center gap-3">
38+
{!props.isError && (
39+
<div className="flex flex-col items-center">
40+
<div className="mb-3 flex size-11 items-center justify-center rounded-full border bg-card">
41+
<UploadIcon className="size-5" />
42+
</div>
43+
<h2 className="mb-0.5 text-center font-medium text-lg">
44+
{props.title}
45+
</h2>
46+
<p className="text-center font-medium text-muted-foreground text-sm">
47+
{props.description}
48+
</p>
49+
</div>
50+
)}
51+
52+
{props.isError && (
53+
<div className="flex flex-col items-center">
54+
<div className="mb-3 flex size-11 items-center justify-center rounded-full border border-red-500 bg-red-200/50 text-red-500 dark:border-red-900 dark:bg-red-900/30 dark:text-foreground">
55+
<XIcon className="size-5" />
56+
</div>
57+
<h2 className="mb-0.5 text-center font-medium text-foreground text-lg">
58+
{props.title}
59+
</h2>
60+
<p className="text-balance text-center text-sm">
61+
{props.description}
62+
</p>
63+
64+
{resetButton && (
65+
<Button
66+
className="relative z-50 mt-4"
67+
size="sm"
68+
onClick={(e) => {
69+
e.stopPropagation();
70+
resetButton.onClick();
71+
}}
72+
>
73+
{resetButton.label}
74+
</Button>
75+
)}
76+
</div>
77+
)}
78+
</div>
79+
</div>
80+
);
81+
}

apps/dashboard/src/@/components/ui/decimal-input.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@ export function DecimalInput(props: {
66
id?: string;
77
className?: string;
88
placeholder?: string;
9+
disabled?: boolean;
910
}) {
1011
return (
1112
<Input
1213
id={props.id}
1314
type="text"
1415
value={props.value}
16+
placeholder={props.placeholder}
1517
className={props.className}
1618
inputMode="decimal"
17-
placeholder={props.placeholder}
19+
disabled={props.disabled}
1820
onChange={(e) => {
1921
const number = Number(e.target.value);
2022
// ignore if string becomes invalid number

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/snapshot-upload.tsx

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { cn } from "@/lib/utils";
1313
import { useCsvUpload } from "hooks/useCsvUpload";
1414
import { CircleAlertIcon, DownloadIcon, UploadIcon } from "lucide-react";
1515
import { useRef } from "react";
16+
import { useDropzone } from "react-dropzone";
1617
import type { Column } from "react-table";
1718
import { type ThirdwebClient, ZERO_ADDRESS } from "thirdweb";
1819
import { CsvDataTable } from "../csv-data-table";
@@ -52,23 +53,18 @@ const SnapshotViewerSheetContent: React.FC<SnapshotUploadProps> = ({
5253
onClose,
5354
client,
5455
}) => {
55-
const {
56-
normalizeQuery,
57-
getInputProps,
58-
getRootProps,
59-
isDragActive,
60-
rawData,
61-
noCsv,
62-
reset,
63-
removeInvalid,
64-
} = useCsvUpload<SnapshotAddressInput>({
56+
const csvUpload = useCsvUpload<SnapshotAddressInput>({
6557
csvParser,
6658
defaultRawData: value,
6759
client,
6860
});
6961

62+
const dropzone = useDropzone({
63+
onDrop: csvUpload.setFiles,
64+
});
65+
7066
const paginationPortalRef = useRef<HTMLDivElement>(null);
71-
const normalizeData = normalizeQuery.data;
67+
const normalizeData = csvUpload.normalizeQuery.data;
7268

7369
if (!normalizeData) {
7470
return (
@@ -152,11 +148,11 @@ const SnapshotViewerSheetContent: React.FC<SnapshotUploadProps> = ({
152148

153149
return (
154150
<div className="flex flex-col gap-6">
155-
{rawData.length > 0 ? (
151+
{csvUpload.rawData.length > 0 ? (
156152
<div>
157153
<CsvDataTable<SnapshotAddressInput>
158154
portalRef={paginationPortalRef}
159-
data={normalizeQuery.data.result}
155+
data={csvUpload.normalizeQuery.data.result}
160156
columns={columns}
161157
/>
162158
</div>
@@ -166,23 +162,27 @@ const SnapshotViewerSheetContent: React.FC<SnapshotUploadProps> = ({
166162
<div
167163
className={cn(
168164
"flex h-full cursor-pointer rounded-md border border-border hover:border-primary",
169-
noCsv ? "bg-red-200" : "bg-background",
165+
csvUpload.noCsv ? "bg-red-200" : "bg-background",
170166
)}
171-
{...getRootProps()}
167+
{...dropzone.getRootProps()}
172168
>
173-
<input {...getInputProps()} />
169+
<input {...dropzone.getInputProps()} />
174170
<div className="!m-auto flex flex-col">
175171
<UploadIcon
176172
className={cn(
177173
"mx-auto mb-2 size-8",
178-
noCsv ? "text-red-500" : "text-gray-600",
174+
csvUpload.noCsv ? "text-red-500" : "text-gray-600",
179175
)}
180176
/>
181-
{isDragActive ? (
177+
{dropzone.isDragActive ? (
182178
<p>Drop the files here</p>
183179
) : (
184-
<p className={noCsv ? "text-red-500" : "text-gray-600"}>
185-
{noCsv
180+
<p
181+
className={
182+
csvUpload.noCsv ? "text-red-500" : "text-gray-600"
183+
}
184+
>
185+
{csvUpload.noCsv
186186
? `No valid CSV file found, make sure your CSV includes the "address" column.`
187187
: "Drag & Drop a CSV file here"}
188188
</p>
@@ -294,20 +294,20 @@ const SnapshotViewerSheetContent: React.FC<SnapshotUploadProps> = ({
294294
<div className="mt-4 flex w-full flex-row items-center gap-2 md:mt-0 md:w-auto">
295295
<Button
296296
className="w-full rounded-md md:w-auto"
297-
disabled={isDisabled || rawData.length === 0}
297+
disabled={isDisabled || csvUpload.rawData.length === 0}
298298
onClick={() => {
299-
reset();
299+
csvUpload.reset();
300300
}}
301301
>
302302
Reset
303303
</Button>
304-
{normalizeQuery.data?.invalidFound ? (
304+
{csvUpload.normalizeQuery.data?.invalidFound ? (
305305
<Button
306306
className="w-full rounded-md md:w-auto"
307307
variant="primary"
308-
disabled={isDisabled || rawData.length === 0}
308+
disabled={isDisabled || csvUpload.rawData.length === 0}
309309
onClick={() => {
310-
removeInvalid();
310+
csvUpload.removeInvalid();
311311
}}
312312
>
313313
Remove invalid
@@ -317,7 +317,7 @@ const SnapshotViewerSheetContent: React.FC<SnapshotUploadProps> = ({
317317
className="w-full rounded-md md:w-auto"
318318
variant="primary"
319319
onClick={onSave}
320-
disabled={isDisabled || rawData.length === 0}
320+
disabled={isDisabled || csvUpload.rawData.length === 0}
321321
>
322322
Next
323323
</Button>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ const uploadMetadataFormSchema = z.object({
3939
description: z.string().optional(),
4040
image: fileBufferOrStringSchema.optional(),
4141
animationUri: fileBufferOrStringSchema.optional(),
42-
external_url: fileBufferOrStringSchema.optional(),
42+
external_url: z.string().optional(),
4343
background_color: z
4444
.string()
4545
.refine(

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

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,6 @@ export function AdvancedNFTMetadataFormGroup<
2929
const form =
3030
props.form as unknown as UseFormReturn<AdvancedNFTMetadataFormGroupValues>;
3131

32-
const externalUrl = form.watch("external_url");
33-
const externalIsTextFile =
34-
externalUrl instanceof File &&
35-
(externalUrl.type.includes("text") || externalUrl.type.includes("pdf"));
36-
3732
return (
3833
<div className="flex flex-col gap-5">
3934
<FormField
@@ -96,21 +91,19 @@ export function AdvancedNFTMetadataFormGroup<
9691
)}
9792
/>
9893

99-
{!externalIsTextFile && (
100-
<FormFieldSetup
101-
errorMessage={form.formState.errors.external_url?.message}
102-
htmlFor="external-url"
103-
isRequired={false}
104-
label="External URL"
105-
helperText="This is the URL that will appear below the asset's image on OpenSea and will allow users to leave OpenSea and view the item on your site."
106-
>
107-
<Input
108-
placeholder="https://"
109-
{...form.register("external_url")}
110-
type="url"
111-
/>
112-
</FormFieldSetup>
113-
)}
94+
<FormFieldSetup
95+
errorMessage={form.formState.errors.external_url?.message}
96+
htmlFor="external-url"
97+
isRequired={false}
98+
label="External URL"
99+
helperText="This is the URL that will appear below the asset's image on OpenSea and will allow users to leave OpenSea and view the item on your site."
100+
>
101+
<Input
102+
placeholder="https://"
103+
{...form.register("external_url")}
104+
type="url"
105+
/>
106+
</FormFieldSetup>
114107
</div>
115108
);
116109
}

0 commit comments

Comments
 (0)