Add defaultCryptoId prop to SellForm and enhance usability
Introduced a new defaultCryptoId prop for the SellForm component to pre-select a cryptocurrency on mount. Adjusted responsive layout and usability for various components including headers, modals, and navigation links. Ensured better user feedback and message clarity for login and registration processes.
This commit is contained in:
parent
e3aa219389
commit
b6f50dc944
@ -27,18 +27,18 @@ export default function RootLayout({
|
||||
<body className={"w-full min-h-screen flex flex-col items-center justify-between"}>
|
||||
<Providers>
|
||||
<Header>
|
||||
<div className={"flex flex-row flex-wrap md:flex-nowrap gap-2"}>
|
||||
<Button asChild variant={"light"}>
|
||||
<Link href={"/wallet"}><p className={"lg:text-lg"}>Wallet</p></Link>
|
||||
<nav className="flex flex-row flex-wrap md:flex-nowrap gap-2">
|
||||
<Button asChild variant="light">
|
||||
<Link href="/wallet" title={"Go to your wallet"}><p className="lg:text-lg">Wallet</p></Link>
|
||||
</Button>
|
||||
<Button asChild variant={"light"}>
|
||||
<Link href={"/dashboard"}><p className={"lg:text-lg"}>Explore cryptos</p></Link>
|
||||
<Button asChild variant="light">
|
||||
<Link href="/dashboard" title={"Go to the crypto explorer"}><p className="lg:text-lg">Explore cryptos</p></Link>
|
||||
</Button>
|
||||
</div>
|
||||
</nav>
|
||||
</Header>
|
||||
{children}
|
||||
<Toaster />
|
||||
<Footer />
|
||||
<Toaster/>
|
||||
<Footer/>
|
||||
</Providers>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -23,6 +23,9 @@ export default function HomePage() {
|
||||
<Button>Get Started</Button>
|
||||
<Button variant="outline">Learn More</Button>
|
||||
</div>
|
||||
<p className="mx-auto max-w-[700px] text-destructive/50 md:text-lg">
|
||||
This website is fictional and for demonstration purposes only.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
@ -13,26 +13,11 @@ interface IParams {
|
||||
}
|
||||
|
||||
export default function SellCryptoPage({ params }: SellCryptoPageProps) {
|
||||
console.log(params);
|
||||
return (
|
||||
<main className="flex flex-col sm:flex-row items-center justify-center w-full h-full gap-4 sm:p-4">
|
||||
<section className={"w-full sm:w-1/3 h-full p-0.5 sm:p-2 flex flex-col items-center justify-center gap-4"}>
|
||||
{/* Graph demande achat/you/other */}
|
||||
<div className={"w-full h-1/3 rounded bg-card text-card-foreground"}>
|
||||
Graph
|
||||
</div>
|
||||
{/* stats */}
|
||||
<div className={"w-full h-2/3 rounded bg-card text-card-foreground"}>
|
||||
Stats
|
||||
</div>
|
||||
</section>
|
||||
<section className={"w-full sm:w-2/3 h-full p-0.5 sm:p-2 flex flex-col items-center justify-center gap-4"}>
|
||||
{/* Formulaire */}
|
||||
<div className={"w-full h-2/3 rounded bg-card text-card-foreground p-2"}>
|
||||
Formulaire
|
||||
<SellForm defaultCryptoId={params.cryptoId}/>
|
||||
</div>
|
||||
{/* Tab Liste offfres vente existante */}
|
||||
<OfferList className={"w-full h-1/3"} trades={[]}/>
|
||||
<main className="flex flex-col sm:flex-row items-center justify-center w-full h-full gap-4 p-2 sm:p-4">
|
||||
<section className={"w-full lg:w-1/3 h-full p-0.5 sm:p-2 flex flex-col items-center justify-center gap-4"}>
|
||||
<SellForm defaultCryptoId={params.cryptoId}/>
|
||||
</section>
|
||||
</main>
|
||||
);
|
||||
|
@ -179,7 +179,7 @@ export function AuthForms() {
|
||||
}
|
||||
//toast.custom(<ToastBox message={"Login successful ! \n You will be redirected."} type={toastType.success}/>)
|
||||
toast({
|
||||
description: "Login successful ! \n You will be redirected.",
|
||||
description: "Login successful ! \n You will be redirected to the home page.",
|
||||
});
|
||||
setTimeout(() => {
|
||||
setIsLoading(false);
|
||||
@ -248,9 +248,9 @@ export function AuthForms() {
|
||||
<p>Register</p>
|
||||
</AutoFormSubmit>
|
||||
<p className="text-gray-500 text-sm">
|
||||
By submitting this form, you agree to our{" "}
|
||||
<Link href="#" className="text-primary underline">
|
||||
terms and conditions
|
||||
By submitting this form, you agree to the{" "}
|
||||
<Link title={"Go to legal page"} href="/legal" className="text-primary underline">
|
||||
GDPR Compliance Policy & Usage Policy
|
||||
</Link>
|
||||
.
|
||||
</p>
|
||||
|
@ -4,29 +4,27 @@ import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog";
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
FormDescription,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
Select,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
} from "@/components/ui/select";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { toast } from "@/components/ui/use-toast";
|
||||
import type { IApiAllOffersRes, IApiDoTradeReq } from "@/interfaces/api.interface";
|
||||
import type { IApiAllOffersRes } from "@/interfaces/api.interface";
|
||||
import type { ICryptoInWalletInfo } from "@/interfaces/crypto.interface";
|
||||
import ApiRequest from "@/services/apiRequest";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { Ban, DollarSign, RefreshCw } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import * as React from "react";
|
||||
import { Dispatch, SetStateAction, useEffect, useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import * as z from "zod";
|
||||
type Props = {
|
||||
@ -43,6 +41,7 @@ export function BuyModal(props: Props) {
|
||||
ApiRequest.authenticated.get
|
||||
.json<IApiAllOffersRes[]>(`offer/crypto/${props.cryptoData.id}`)
|
||||
.then((response) => {
|
||||
console.debug(response)
|
||||
if (response.data) {setOffersList(response.data)}
|
||||
console.log(`Crypto ${props.cryptoData.name} -> ${response.data.length}`);
|
||||
setIsLoaded(true);
|
||||
@ -157,7 +156,10 @@ export function BuyModal(props: Props) {
|
||||
{offersList.length}
|
||||
</p>
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="server">Buy from server</TabsTrigger>
|
||||
<TabsTrigger value="server">Buy from server{" "}<p
|
||||
className={" ml-1 px-1 bg-primary text-primary-foreground rounded"}>
|
||||
{props.cryptoData.quantity}
|
||||
</p></TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent
|
||||
value="user"
|
||||
@ -171,30 +173,28 @@ export function BuyModal(props: Props) {
|
||||
<FormField
|
||||
control={buyFromUserForm.control}
|
||||
name="offerId"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Select an offer</FormLabel>
|
||||
<Select onValueChange={field.onChange} defaultValue={field.value}>
|
||||
<FormControl>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select an offer to purchase." />
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
{offersList.map((offer) => {
|
||||
if (!offer) return;
|
||||
return (
|
||||
<SelectItem
|
||||
value={offer.id}
|
||||
key={offer.id}
|
||||
>{`${offer.amount}x ${offer.Crypto.name} - ${offer.User.pseudo}`}</SelectItem>
|
||||
);
|
||||
})}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Select an offer</FormLabel>
|
||||
<Select defaultValue={offersList[0]?.id} onValueChange={(val) => {
|
||||
console.log(val);
|
||||
field.onChange(val);
|
||||
}}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select an offer to purchase."/>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{offersList.map((offer) => (
|
||||
<SelectItem
|
||||
value={offer.id}
|
||||
key={offer.id}
|
||||
>{`${offer.amount}x ${offer.Crypto.name}`}</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<Button type="submit">Submit</Button>
|
||||
</form>
|
||||
|
@ -13,8 +13,9 @@ import type { IUserWallet } from "@/interfaces/userdata.interface";
|
||||
import type {
|
||||
ColumnDef,
|
||||
} from "@tanstack/react-table";
|
||||
import { ArrowUpDown, MoreHorizontal } from "lucide-react";
|
||||
import { ArrowUpDown, MoreHorizontal, Receipt } from "lucide-react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import Link from "next/link";
|
||||
|
||||
interface DataTableProps<TData, TValue> {
|
||||
columns: ColumnDef<TData, TValue>[];
|
||||
@ -68,8 +69,8 @@ export function WalletTable(props: Props) {
|
||||
const payment = row.original;
|
||||
|
||||
return (
|
||||
<div className={"flex gap-2"}>
|
||||
<p className={"font-light italic text-xs"}>Soon here : Sell, History</p>
|
||||
<div>
|
||||
<Link href={`/sell/${row.original.id}`} className={"flex w-fit gap-2 p-2 justify-center items-center rounded hover:bg-card"}><Receipt /> <p className={"hidden sm:block"}>Sell for USD</p></Link>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
@ -11,7 +11,7 @@ export function Header({
|
||||
return (
|
||||
<header
|
||||
className={
|
||||
"flex flex-col md:flex-row justify-between items-center w-full p-1 md:px-3 md:py-2 pb-2 border-b-2"
|
||||
"flex flex-col md:flex-row justify-between items-center w-full p-1 md:px-3 gap-2 md:py-2 pb-2 border-b-2"
|
||||
}
|
||||
>
|
||||
<Link title={"Return to home page"} href={"/"} className={"flex flex-row justify-center md:justify-start items-center w-fit gap-2"}>
|
||||
|
@ -15,7 +15,11 @@ import { Slider } from "@/components/ui/slider";
|
||||
import { DollarSign, Equal, X } from "lucide-react";
|
||||
import { Card } from "@/components/ui/card";
|
||||
|
||||
export function SellForm() {
|
||||
interface SellFormProps {
|
||||
defaultCryptoId?: string;
|
||||
}
|
||||
|
||||
export function SellForm({ defaultCryptoId }: SellFormProps) {
|
||||
const [currentWallet, setCurrentWallet] = useState<IUserWalletCryptos[]>();
|
||||
const [sliderValue, setSliderValue] = useState(0);
|
||||
const [quantity, setQuantity] = useState(0);
|
||||
@ -29,6 +33,15 @@ export function SellForm() {
|
||||
fetchAssets();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (defaultCryptoId) {
|
||||
const maxShares = getMaxSharesForCrypto(defaultCryptoId);
|
||||
setSliderValue(maxShares);
|
||||
setSelectedCrypto(defaultCryptoId);
|
||||
setQuantity(1);
|
||||
}
|
||||
}, []);
|
||||
|
||||
function getMaxSharesForCrypto(cryptoId: string) {
|
||||
return currentWallet?.find((crypto) => crypto.Crypto.id === cryptoId)?.amount || 0;
|
||||
}
|
||||
@ -116,6 +129,7 @@ export function SellForm() {
|
||||
>
|
||||
<FormLabel>Sell shares of your wallet</FormLabel>
|
||||
<Select
|
||||
defaultValue={defaultCryptoId}
|
||||
onValueChange={(val) => {
|
||||
const maxShares = getMaxSharesForCrypto(val);
|
||||
setSliderValue(maxShares);
|
||||
@ -130,11 +144,9 @@ export function SellForm() {
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
{currentWallet?.map((crypto) => (
|
||||
<SelectItem value={crypto.Crypto.id} key={crypto.Crypto.id}>
|
||||
{`${crypto.amount}x ${crypto.Crypto.name} - ${crypto.Crypto.value}$/u`}
|
||||
</SelectItem>
|
||||
))}
|
||||
{currentWallet?.map((crypto) => (<SelectItem value={crypto.Crypto.id} key={crypto.Crypto.id}>
|
||||
{`${crypto.amount}x ${crypto.Crypto.name} - ${Math.round(crypto.Crypto.value)}$/u`}
|
||||
</SelectItem>))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormMessage />
|
||||
|
Loading…
x
Reference in New Issue
Block a user