diff --git a/src/components/cryptos/buy-modal.tsx b/src/components/cryptos/buy-modal.tsx new file mode 100644 index 0000000..9765fe2 --- /dev/null +++ b/src/components/cryptos/buy-modal.tsx @@ -0,0 +1,193 @@ +// @flow +import * as React from 'react'; +import { + Dialog, + DialogContent, + DialogTrigger, +} from "@/components/ui/dialog"; +import {Button} from "@/components/ui/button"; +import {Ban, DollarSign, RefreshCw} from "lucide-react"; +import * as z from "zod"; +import {Tabs, TabsContent, TabsList, TabsTrigger} from "@/components/ui/tabs"; +import {Dispatch, SetStateAction, useEffect, useState} from "react"; +import type {ICryptoInWalletInfo} from "@/interfaces/crypto.interface"; +import {toast} from "@/components/ui/use-toast"; +import AutoForm, {AutoFormSubmit} from "@/components/auto-form"; +import type {IApiAllOffersRes, IApiDoTradeReq} from "@/interfaces/api.interface"; +import ApiRequest from "@/services/apiRequest"; +import {Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage} from "@/components/ui/form"; +import {Select, SelectContent, SelectItem, SelectTrigger, SelectValue} from "@/components/ui/select"; +import Link from "next/link"; +import {useForm} from "react-hook-form"; +import {zodResolver} from "@hookform/resolvers/zod"; +type Props = { + cryptoData: ICryptoInWalletInfo +}; +export function BuyModal(props: Props) { + const [isLoading, setIsLoading] = useState(false) + const [offersList, setOffersList] = useState([]) + const [isLoaded,setIsLoaded] = useState(false) + + // biome-ignore lint/correctness/useExhaustiveDependencies: + useEffect(() => { + if(!isLoaded) { + ApiRequest.authenticated.get.json(`offer/crypto/${props.cryptoData.id}`).then((response) => { + setOffersList(response.data); + console.log(`Crypto ${props.cryptoData.name} -> ${response.data.length}`) + setIsLoaded(true); + return; + }) + } + }, [isLoaded]); + + const buyFromServerSchema = z.object({ + amount: z + .number({ + required_error: "An amount is needed.", + }) + .min(1) + .max(props.cryptoData.quantity, "You cant buy more that what is available on the server.") + .describe("The amount you want to buy."), + }); + + const buyFromUserSchema = z.object({ + offerId: z + .string({ + required_error: "You should select an offer.", + }) + .uuid(), + }) + + function onBuyFromServerSubmit(data: z.infer) { + ApiRequest.authenticated.post.json("crypto/buy", {id_crypto: props.cryptoData.id, amount: data.amount}).then((res)=>{ + if (res.status !== 201) { + toast({ + title: "An error occurred !", + description: (
+          {JSON.stringify(res.statusText, null, 2)}
+        
) + }) + return + } + toast({ + title: "Transaction accepted.", + description: ( +

You will be redirected.

+ ) + }) + setTimeout(()=>location.reload(), 1_500) + }) + toast({ + title: "You submitted the following values:", + description: ( +
+          {JSON.stringify(data, null, 2)}
+        
+ ), + }) + } + function onBuyFromUserSubmit(data: z.infer) { + ApiRequest.authenticated.post.json("trade/create", {id_offer: data.offerId}).then((res)=>{ + if (res.status !== 201) { + toast({ + title: "An error occurred !", + description: (
+          {JSON.stringify(res.statusText, null, 2)}
+        
) + }) + return + } + toast({ + title: "Transaction accepted.", + description: ( +

You will be redirected.

+ ) + }) + setTimeout(()=>location.reload(), 1_500) + }) + toast({ + title: "You submitted the following values:", + description: ( +
+          {JSON.stringify(data, null, 2)}
+        
+ ), + }) + } + + const buyFromUserForm = useForm>({ + resolver: zodResolver(buyFromUserSchema), + }) + + return ( + + + + + + + + Buy from user

{offersList.length}

+ Buy from server +
+ +
+ + ( + + Select an offer + + + + )} + /> + + + +
+ + {!props.cryptoData.quantity &&
+ +

The server dont have stock for the designated cryptos.

+
} +
+

Available quantity on the server :

+

{props.cryptoData.quantity}

+
+ {props.cryptoData.quantity && + + {/* biome-ignore lint/style/useTemplate: */} + +

Buy from the server

+
+
} +
+
+
+
+ ); +}; \ No newline at end of file