Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: integrate new token actions flow #32

Merged
merged 5 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
"use client";

import { useState } from "react";
import { useCreateAuction, useCreateListing } from "@ark-project/react";
import { zodResolver } from "@hookform/resolvers/zod";
import { useAccount } from "@starknet-react/core";
import { ShoppingBag } from "lucide-react";
import moment from "moment";
import { useForm } from "react-hook-form";
import { parseEther } from "viem";
import * as z from "zod";

import { Button } from "@ark-market/ui/button";
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@ark-market/ui/dialog";
import {
Form,
FormControl,
Expand All @@ -29,9 +38,10 @@ import {

import type { Token, TokenMarketData } from "~/types";
import { env } from "~/env";
import TokenMedia from "./token-media";

interface CreateListingProps {
token?: Token;
token: Token;
tokenMarketData?: TokenMarketData;
}

Expand All @@ -50,17 +60,10 @@ const formSchema = z.object({
duration: z.string(),
type: z.enum([FIXED, AUCTION]),
});
// .refine(
// (data) =>
// data.type === AUCTION ? data.endAmount > data.startAmount : true,
// {
// message: "Reserve price must be greater than starting price",
// path: ["endAmount"]
// }
// );

const CreateListing: React.FC<CreateListingProps> = ({ token }) => {
const { account } = useAccount();
const [isOpen, setIsOpen] = useState(false);
const { createListing, status } = useCreateListing();
const { create: createAuction, status: auctionStatus } = useCreateAuction();

Expand All @@ -75,15 +78,9 @@ const CreateListing: React.FC<CreateListingProps> = ({ token }) => {
});

async function onSubmit(values: z.infer<typeof formSchema>) {
if (account === undefined || !token?.contract_address || !token.token_id) {
console.error("Account, token address, or token ID is missing");
return;
}

const tokenId = parseInt(token.token_id, 10);

if (isNaN(tokenId)) {
console.error("Invalid tokenId");
if (!account) {
// TODO: Handle error with toast
console.error("Account is missing");
return;
}

Expand Down Expand Up @@ -123,124 +120,147 @@ const CreateListing: React.FC<CreateListingProps> = ({ token }) => {
}

const isAuction = form.getValues("type") === AUCTION;
const duration = form.watch("duration");
const expiredAt = moment().add(duration, "hours").format("LLLL");
// const duration = form.watch("duration");
// const expiredAt = moment().add(duration, "hours").format("LLLL");
const isLoading = status === "loading" || auctionStatus === "loading";

return (
<div className="w-full rounded border p-4">
<div className="mb-4 font-semibold">List for sale</div>
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="flex flex-col space-y-4"
>
<FormField
control={form.control}
name="type"
render={({ field }) => (
<FormItem className="">
<FormLabel>Choose a type of sale</FormLabel>
<FormControl>
<RadioGroup
onValueChange={field.onChange}
defaultValue={field.value}
className="gap-0 rounded border"
>
<FormItem className="flex items-center justify-center border-b p-4">
<FormLabel className="flex flex-grow flex-col space-y-2 font-normal">
<span className="font-semibold">Fixed price</span>
<span className="">
The item is listed at the price you set.
</span>
</FormLabel>
<FormControl>
<RadioGroupItem value={FIXED} className="h-6 w-6" />
</FormControl>
</FormItem>
<FormItem className="flex items-center justify-center p-4">
<FormLabel className="flex flex-grow flex-col space-y-2 font-normal">
<span className="font-semibold">
Sell to highest bidder
</span>
<span className="">
The item is listed for auction.
</span>
</FormLabel>
<FormControl>
<RadioGroupItem value={AUCTION} className="h-6 w-6" />
</FormControl>
</FormItem>
</RadioGroup>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="startAmount"
render={({ field }) => (
<FormItem>
<FormLabel>Starting Price</FormLabel>
<FormControl>
<Input placeholder="Amount" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
{isAuction && (
<Dialog open={isOpen} onOpenChange={setIsOpen}>
<DialogTrigger
asChild
className="mx-auto flex max-w-[416px] flex-col items-center gap-4 lg:flex-row lg:gap-8"
>
<Button className="relative w-full" size="xl">
<ShoppingBag size={24} className="absolute left-4" />
<span>List for sale</span>
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader className="items-center">
<DialogTitle>List for sale</DialogTitle>
</DialogHeader>
<div className="flex items-center space-x-4">
<div className="size-24 overflow-hidden rounded">
<TokenMedia token={token} />
</div>
<div className="">
<div className="font-bold">Duo #{token.token_id}</div>
<div className="text-muted-foreground">Everai</div>
</div>
<div className="grow" />
</div>
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="flex flex-col space-y-4"
>
<FormField
control={form.control}
name="endAmount"
name="type"
render={({ field }) => (
<FormItem>
<FormLabel>Reserve Price</FormLabel>
<FormItem className="">
<FormLabel>Choose a type of sale</FormLabel>
<FormControl>
<Input placeholder="Amount" {...field} />
<RadioGroup
onValueChange={field.onChange}
defaultValue={field.value}
className="gap-0 rounded border"
>
<FormItem className="flex items-center justify-center border-b p-4">
<FormLabel className="text-md flex flex-grow flex-col space-y-2 font-normal">
<span className="font-semibold">Fixed price</span>
<span className="">
The item is listed at the price you set.
</span>
</FormLabel>
<FormControl>
<RadioGroupItem value={FIXED} className="h-6 w-6" />
</FormControl>
</FormItem>
<FormItem className="flex items-center justify-center p-4">
<FormLabel className="text-md flex flex-grow flex-col space-y-2 font-normal">
<span className="font-semibold">
Sell to highest bidder
</span>
<span className="">
The item is listed for auction.
</span>
</FormLabel>
<FormControl>
<RadioGroupItem value={AUCTION} className="h-6 w-6" />
</FormControl>
</FormItem>
</RadioGroup>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
)}
<FormField
control={form.control}
name="duration"
render={({ field }) => (
<FormItem>
<div className="flex justify-between">
<FormLabel>Duration</FormLabel>
<div className="text-sm">Expires {expiredAt}</div>
</div>
<Select
onValueChange={field.onChange}
defaultValue={field.value.toString()}
>
<FormField
control={form.control}
name="startAmount"
render={({ field }) => (
<FormItem>
<FormLabel>Set starting price</FormLabel>
<FormControl>
<SelectTrigger className="">
<SelectValue placeholder="Theme" />
</SelectTrigger>
<Input placeholder="Amount" {...field} />
</FormControl>
<SelectContent>
<SelectItem value="1">1 hour</SelectItem>
<SelectItem value="3">3 hours</SelectItem>
<SelectItem value="6">6 hours</SelectItem>
<SelectItem value="24">1 day</SelectItem>
<SelectItem value="72">3 days</SelectItem>
</SelectContent>
</Select>
<FormMessage />
</FormItem>
<FormMessage />
</FormItem>
)}
/>
{isAuction && (
<FormField
control={form.control}
name="endAmount"
render={({ field }) => (
<FormItem>
<FormLabel>Set reserve price</FormLabel>
<FormControl>
<Input placeholder="Amount" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
)}
/>
<Button type="submit" className="" disabled={isLoading}>
{isLoading ? "Loading..." : "Complete Listing"}
</Button>
</form>
</Form>
</div>
<FormField
control={form.control}
name="duration"
render={({ field }) => (
<FormItem>
<div className="flex justify-between">
<FormLabel>Set expiration</FormLabel>
{/* <div className="text-sm">Expires {expiredAt}</div> */}
</div>
<Select
onValueChange={field.onChange}
defaultValue={field.value.toString()}
>
<FormControl>
<SelectTrigger className="">
<SelectValue placeholder="Theme" />
</SelectTrigger>
</FormControl>
<SelectContent>
<SelectItem value="1">1 hour</SelectItem>
<SelectItem value="3">3 hours</SelectItem>
<SelectItem value="6">6 hours</SelectItem>
<SelectItem value="24">1 day</SelectItem>
<SelectItem value="72">3 days</SelectItem>
</SelectContent>
</Select>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit" className="" disabled={isLoading}>
{isLoading ? "Loading..." : "Complete Listing"}
</Button>
</form>
</Form>
</DialogContent>
</Dialog>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import TokenMedia from "./token-media";

interface CreateOfferProps {
token: Token;
tokenMarketData: TokenMarketData | undefined;
tokenMarketData?: TokenMarketData;
}

export default function CreateOffer({
Expand Down
2 changes: 1 addition & 1 deletion apps/arkmarket/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export default function RootLayout({ children }: PropsWithChildren) {
{children}
<SpeedInsights />
</div>
<Toaster />
<Toaster richColors />
<Footer />
<DataFooter className="fixed bottom-0 hidden w-full lg:flex" />
</Providers>
Expand Down
Loading
Loading