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:
Mathis H (Avnyr) 2024-11-24 23:50:12 +01:00
parent e3aa219389
commit b6f50dc944
Signed by: Mathis
GPG Key ID: DD9E0666A747D126
8 changed files with 76 additions and 75 deletions

View File

@ -27,14 +27,14 @@ 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/>

View File

@ -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>

View File

@ -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
<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}/>
</div>
{/* Tab Liste offfres vente existante */}
<OfferList className={"w-full h-1/3"} trades={[]}/>
</section>
</main>
);

View File

@ -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>

View File

@ -4,7 +4,6 @@ import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog";
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
@ -12,21 +11,20 @@ import {
} from "@/components/ui/form";
import {
Select,
SelectContent,
SelectItem,
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"
@ -174,22 +176,20 @@ export function BuyModal(props: Props) {
render={({ field }) => (
<FormItem>
<FormLabel>Select an offer</FormLabel>
<Select onValueChange={field.onChange} defaultValue={field.value}>
<FormControl>
<Select defaultValue={offersList[0]?.id} onValueChange={(val) => {
console.log(val);
field.onChange(val);
}}>
<SelectTrigger>
<SelectValue placeholder="Select an offer to purchase."/>
</SelectTrigger>
</FormControl>
<SelectContent>
{offersList.map((offer) => {
if (!offer) return;
return (
{offersList.map((offer) => (
<SelectItem
value={offer.id}
key={offer.id}
>{`${offer.amount}x ${offer.Crypto.name} - ${offer.User.pseudo}`}</SelectItem>
);
})}
>{`${offer.amount}x ${offer.Crypto.name}`}</SelectItem>
))}
</SelectContent>
</Select>
<FormMessage />

View File

@ -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>
);
},

View File

@ -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"}>

View File

@ -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 />