Skip to content

Commit c0b8868

Browse files
committed
updated creation flow
1 parent 75c6d7f commit c0b8868

File tree

3 files changed

+335
-53
lines changed

3 files changed

+335
-53
lines changed

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/assets/create-token/page.tsx

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,27 @@ export default function CreateTokenPage() {
161161
const renderStepIndicators = () => (
162162
<div className="flex justify-center mb-8 pt-6">
163163
<div className="relative flex w-full max-w-md justify-between">
164-
{/* Connect line between circles */}
165-
<div className="absolute top-5 left-0 right-0 h-0.5 -translate-y-1/2 bg-muted" />
164+
{/* Segmented lines between circles instead of a single line */}
165+
<div className="absolute top-5 left-0 right-0 flex justify-between">
166+
{/* First segment: between step 1 and 2 */}
167+
<div className="w-1/2 flex items-center">
168+
<div
169+
className={`h-0.5 w-full ${
170+
step > 1 ? "bg-primary/20" : "bg-muted"
171+
}`}
172+
style={{ marginLeft: "25px", marginRight: "25px" }}
173+
/>
174+
</div>
175+
{/* Second segment: between step 2 and 3 */}
176+
<div className="w-1/2 flex items-center">
177+
<div
178+
className={`h-0.5 w-full ${
179+
step > 2 ? "bg-primary/20" : "bg-muted"
180+
}`}
181+
style={{ marginLeft: "25px", marginRight: "25px" }}
182+
/>
183+
</div>
184+
</div>
166185

167186
<StepIndicator step={1} currentStep={step} label="Token Info" />
168187
<StepIndicator step={2} currentStep={step} label="Token Options" />
@@ -342,7 +361,7 @@ export default function CreateTokenPage() {
342361
</FormFieldSetup>
343362

344363
<FormFieldSetup
345-
label="Airdrop % of supply to:"
364+
label="Airdrop % of supply to list:"
346365
isRequired
347366
errorMessage={
348367
advancedOptionsForm.formState.errors.airdropSupply?.message
Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
"use client";
2+
3+
import { FormFieldSetup } from "@/components/blocks/FormFieldSetup";
4+
import { Button } from "@/components/ui/button";
5+
import {
6+
Select,
7+
SelectContent,
8+
SelectItem,
9+
SelectTrigger,
10+
SelectValue,
11+
} from "@/components/ui/select";
12+
import { Separator } from "@/components/ui/separator";
13+
import { cn } from "@/lib/utils";
14+
import { zodResolver } from "@hookform/resolvers/zod";
15+
import { ArrowLeftIcon, ArrowRightIcon, CheckIcon } from "lucide-react";
16+
import { useState } from "react";
17+
import { useForm } from "react-hook-form";
18+
import * as z from "zod";
19+
import { Fieldset } from "components/contract-components/contract-deploy-form/common";
20+
import { SolidityInput } from "contract-ui/components/solidity-inputs";
21+
import { Form } from "@/components/ui/form";
22+
23+
// Form schema
24+
const contractDetailsSchema = z.object({
25+
contractAddress: z.string().min(1, "Contract address is required"),
26+
network: z.string().min(1, "Network is required"),
27+
});
28+
29+
type ContractDetailsValues = z.infer<typeof contractDetailsSchema>;
30+
31+
// Step indicator component
32+
const StepIndicator = ({
33+
step,
34+
currentStep,
35+
label,
36+
}: {
37+
step: number;
38+
currentStep: number;
39+
label: string;
40+
}) => (
41+
<div className="flex flex-col items-center space-y-2">
42+
<div
43+
className={cn(
44+
"flex h-10 w-10 items-center justify-center rounded-full text-sm font-medium",
45+
currentStep === step
46+
? "bg-primary text-primary-foreground"
47+
: currentStep > step
48+
? "bg-primary/20 text-primary"
49+
: "bg-muted text-muted-foreground"
50+
)}
51+
>
52+
{currentStep > step ? (
53+
<CheckIcon className="h-5 w-5" />
54+
) : (
55+
<span>{step}</span>
56+
)}
57+
</div>
58+
<span className="text-xs font-medium">{label}</span>
59+
</div>
60+
);
61+
62+
export default function ImportAssetPage() {
63+
const [step, setStep] = useState<number>(1);
64+
const [contractDetails, setContractDetails] =
65+
useState<ContractDetailsValues>();
66+
67+
// Form
68+
const contractDetailsForm = useForm<ContractDetailsValues>({
69+
resolver: zodResolver(contractDetailsSchema),
70+
defaultValues: {
71+
contractAddress: "",
72+
network: "Ethereum",
73+
},
74+
});
75+
76+
// Step handlers
77+
const onContractDetailsSubmit = (data: ContractDetailsValues) => {
78+
setContractDetails(data);
79+
setStep(2);
80+
};
81+
82+
const goBack = () => {
83+
if (step > 1) {
84+
setStep(step - 1);
85+
}
86+
};
87+
88+
// Render functions
89+
const renderStepIndicators = () => (
90+
<div className="flex justify-center mb-8 pt-6">
91+
<div className="relative flex w-full max-w-md justify-between">
92+
{/* Segmented line between circles */}
93+
<div className="absolute top-5 left-0 right-0 flex justify-center">
94+
<div className="w-1/2 flex items-center">
95+
<div
96+
className={`h-0.5 w-full ${
97+
step > 1 ? "bg-primary/20" : "bg-muted"
98+
}`}
99+
style={{ marginLeft: "25px", marginRight: "25px" }}
100+
/>
101+
</div>
102+
</div>
103+
104+
<StepIndicator step={1} currentStep={step} label="Contract Details" />
105+
<StepIndicator step={2} currentStep={step} label="Overview" />
106+
</div>
107+
</div>
108+
);
109+
110+
const renderStep1 = () => (
111+
<div className="w-full max-w-4xl mx-auto">
112+
<h1 className="text-2xl font-bold mb-6">Import Asset</h1>
113+
<p className="text-sm text-muted-foreground mb-6">
114+
Import an existing token or NFT collection from the blockchain
115+
</p>
116+
117+
{renderStepIndicators()}
118+
119+
<Fieldset legend="Contract Details">
120+
<Form {...contractDetailsForm}>
121+
<form
122+
onSubmit={contractDetailsForm.handleSubmit(onContractDetailsSubmit)}
123+
className="space-y-6"
124+
>
125+
<div className="space-y-6">
126+
<FormFieldSetup
127+
label="Contract Address"
128+
isRequired
129+
htmlFor="contractAddress"
130+
errorMessage={
131+
contractDetailsForm.formState.errors.contractAddress?.message
132+
}
133+
helperText="Enter the address of the contract you want to import"
134+
>
135+
<SolidityInput
136+
id="contractAddress"
137+
solidityType="address"
138+
placeholder="0x..."
139+
{...contractDetailsForm.register("contractAddress", {
140+
required: "Contract address is required",
141+
})}
142+
/>
143+
</FormFieldSetup>
144+
145+
<FormFieldSetup
146+
label="Network"
147+
isRequired
148+
htmlFor="network"
149+
errorMessage={
150+
contractDetailsForm.formState.errors.network?.message
151+
}
152+
helperText="Select the blockchain where the contract is deployed"
153+
>
154+
<Select
155+
defaultValue={contractDetailsForm.watch("network")}
156+
onValueChange={(value) =>
157+
contractDetailsForm.setValue("network", value)
158+
}
159+
>
160+
<SelectTrigger id="network">
161+
<SelectValue placeholder="Select network" />
162+
</SelectTrigger>
163+
<SelectContent>
164+
<SelectItem value="Ethereum">Ethereum</SelectItem>
165+
<SelectItem value="Base">Base</SelectItem>
166+
<SelectItem value="Polygon">Polygon</SelectItem>
167+
<SelectItem value="Arbitrum">Arbitrum</SelectItem>
168+
<SelectItem value="Optimism">Optimism</SelectItem>
169+
</SelectContent>
170+
</Select>
171+
</FormFieldSetup>
172+
</div>
173+
174+
<div className="flex justify-end pt-6">
175+
<Button type="submit">
176+
Next <ArrowRightIcon className="ml-2 h-4 w-4" />
177+
</Button>
178+
</div>
179+
</form>
180+
</Form>
181+
</Fieldset>
182+
</div>
183+
);
184+
185+
const renderStep2 = () => (
186+
<div className="w-full max-w-4xl mx-auto">
187+
<h1 className="text-2xl font-bold mb-6">Import Asset</h1>
188+
<p className="text-sm text-muted-foreground mb-6">
189+
Import an existing token or NFT collection from the blockchain
190+
</p>
191+
192+
{renderStepIndicators()}
193+
194+
<Fieldset legend="Overview">
195+
<div className="space-y-6">
196+
<div>
197+
<h3 className="text-lg font-medium mb-4 flex justify-between">
198+
Contract Details
199+
<Button variant="ghost" size="sm" onClick={() => setStep(1)}>
200+
Edit
201+
</Button>
202+
</h3>
203+
<div className="grid grid-cols-2 gap-4">
204+
<div className="space-y-2">
205+
<p className="text-muted-foreground text-sm">
206+
Contract Address:
207+
</p>
208+
<p className="font-mono">{contractDetails?.contractAddress}</p>
209+
</div>
210+
211+
<div className="space-y-2">
212+
<p className="text-muted-foreground text-sm">Network:</p>
213+
<p>{contractDetails?.network}</p>
214+
</div>
215+
</div>
216+
</div>
217+
218+
<Separator />
219+
220+
<div className="rounded-md bg-muted/50 p-4">
221+
<h3 className="text-base font-medium mb-2">Note:</h3>
222+
<p className="text-sm text-muted-foreground">
223+
Importing this asset will allow you to manage it through the
224+
dashboard. No changes will be made to the contract itself.
225+
</p>
226+
</div>
227+
228+
<div className="flex justify-between pt-6">
229+
<Button type="button" variant="outline" onClick={goBack}>
230+
<ArrowLeftIcon className="mr-2 h-4 w-4" /> Back
231+
</Button>
232+
<Button
233+
type="button"
234+
className="bg-primary hover:bg-primary/90"
235+
onClick={() => alert("Asset would be imported here")}
236+
>
237+
Import Asset <CheckIcon className="ml-2 h-4 w-4" />
238+
</Button>
239+
</div>
240+
</div>
241+
</Fieldset>
242+
</div>
243+
);
244+
245+
// Render the appropriate step
246+
const renderCurrentStep = () => {
247+
switch (step) {
248+
case 1:
249+
return renderStep1();
250+
case 2:
251+
return renderStep2();
252+
default:
253+
return renderStep1();
254+
}
255+
};
256+
257+
return <div className="w-full py-8">{renderCurrentStep()}</div>;
258+
}

0 commit comments

Comments
 (0)