193 lines
8.8 KiB
TypeScript
193 lines
8.8 KiB
TypeScript
|
|
"use client";
|
||
|
|
|
||
|
|
import { useState } from "react";
|
||
|
|
import Image from "next/image";
|
||
|
|
import { Button } from "@heroui/react";
|
||
|
|
import { useApp } from "@/contexts/AppContext";
|
||
|
|
import ConfirmModal from "@/components/common/ConfirmModal";
|
||
|
|
import { buttonStyles, disabledButtonClasses } from "@/lib/buttonStyles";
|
||
|
|
import { cn } from "@/lib/cn";
|
||
|
|
interface TradePanelProps {
|
||
|
|
showHeader?: boolean;
|
||
|
|
title?: string;
|
||
|
|
subtitle?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export default function TradePanel({
|
||
|
|
showHeader = false,
|
||
|
|
title = "",
|
||
|
|
subtitle = "",
|
||
|
|
}: TradePanelProps) {
|
||
|
|
const { t } = useApp();
|
||
|
|
const [sellAmount, setSellAmount] = useState<string>("");
|
||
|
|
const [buyAmount, setBuyAmount] = useState<string>("");
|
||
|
|
const [isConfirmModalOpen, setIsConfirmModalOpen] = useState(false);
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div className={`flex flex-col gap-6 ${showHeader ? "w-full max-w-[600px]" : "w-full"}`}>
|
||
|
|
{/* Header Section - Optional */}
|
||
|
|
{showHeader && (
|
||
|
|
<div className="flex flex-col gap-2">
|
||
|
|
<h1 className="text-heading-h2 font-bold text-text-primary dark:text-white text-center">
|
||
|
|
{title}
|
||
|
|
</h1>
|
||
|
|
<p className="text-body-default font-medium text-text-secondary dark:text-gray-400 text-center">
|
||
|
|
{subtitle}
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
)}
|
||
|
|
|
||
|
|
{/* Trade Panel */}
|
||
|
|
<div className="bg-bg-surface dark:bg-gray-800 rounded-3xl border border-border-gray dark:border-gray-700 p-6">
|
||
|
|
<div className="flex flex-col gap-4">
|
||
|
|
{/* SELL and BUY Container with Exchange Icon */}
|
||
|
|
<div className="flex flex-col gap-2 relative">
|
||
|
|
{/* SELL Section */}
|
||
|
|
<div className="bg-bg-subtle dark:bg-gray-700 rounded-2xl p-4 flex flex-col gap-4">
|
||
|
|
{/* Label and Buttons */}
|
||
|
|
<div className="flex items-center justify-between">
|
||
|
|
<span className="text-body-small font-bold text-text-primary dark:text-white">
|
||
|
|
{t("alp.sell")}
|
||
|
|
</span>
|
||
|
|
<div className="flex items-center gap-2">
|
||
|
|
<Button size="sm" color="default" className="rounded-full px-3 h-[24px] min-w-0 text-[12px] font-bold">
|
||
|
|
25%
|
||
|
|
</Button>
|
||
|
|
<Button size="sm" color="default" className="rounded-full px-3 h-[24px] min-w-0 text-[12px] font-bold">
|
||
|
|
50%
|
||
|
|
</Button>
|
||
|
|
<Button size="sm" color="default" className="rounded-full px-3 h-[24px] min-w-0 text-[12px] font-bold">
|
||
|
|
75%
|
||
|
|
</Button>
|
||
|
|
<Button size="sm" className="rounded-full px-3 h-[24px] min-w-0 text-[12px] font-bold !bg-[#a7f3d0] !text-[#065f46] dark:!bg-green-900/30 dark:!text-green-300 border-none shadow-none">
|
||
|
|
{t("mintSwap.max")}
|
||
|
|
</Button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Input Row */}
|
||
|
|
<div className="flex items-center justify-between gap-2 h-[70px]">
|
||
|
|
<div className="flex flex-col items-start justify-between flex-1 h-full">
|
||
|
|
<input
|
||
|
|
type="number"
|
||
|
|
placeholder="1,000"
|
||
|
|
value={sellAmount}
|
||
|
|
onChange={(e) => setSellAmount(e.target.value)}
|
||
|
|
className="w-full text-left text-[32px] font-bold leading-[130%] tracking-[-0.01em] text-text-primary dark:text-white placeholder:text-[#d1d5db] dark:placeholder:text-gray-500 bg-transparent border-none outline-none [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
|
||
|
|
/>
|
||
|
|
<span className="text-body-small font-medium text-text-tertiary dark:text-gray-400">
|
||
|
|
$10,000.00 USD
|
||
|
|
</span>
|
||
|
|
</div>
|
||
|
|
<div className="flex flex-col items-end justify-between gap-1 h-full">
|
||
|
|
<button className="bg-bg-surface dark:bg-gray-600 rounded-full border border-border-normal dark:border-gray-500 px-3 h-[40px] flex items-center gap-2">
|
||
|
|
<Image
|
||
|
|
src="/usd-coin-usdc-logo-10.svg"
|
||
|
|
alt="USDC"
|
||
|
|
width={24}
|
||
|
|
height={24}
|
||
|
|
/>
|
||
|
|
<span className="text-body-small font-bold text-text-primary dark:text-white">USDC</span>
|
||
|
|
<Image src="/icon8.svg" alt="" width={12} height={12} />
|
||
|
|
</button>
|
||
|
|
<span className="text-caption-tiny font-regular text-text-tertiary dark:text-gray-400">
|
||
|
|
45,230.00 USDC
|
||
|
|
</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Exchange Icon */}
|
||
|
|
<div className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 z-10">
|
||
|
|
<div className="bg-bg-surface dark:bg-gray-700 rounded-full w-10 h-10 flex items-center justify-center border border-border-gray dark:border-gray-600 shadow-sm">
|
||
|
|
<Image
|
||
|
|
src="/icon4.svg"
|
||
|
|
alt="Exchange"
|
||
|
|
width={18}
|
||
|
|
height={18}
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* BUY Section */}
|
||
|
|
<div className="bg-bg-subtle dark:bg-gray-700 rounded-2xl p-4 flex flex-col gap-4">
|
||
|
|
{/* Label */}
|
||
|
|
<div className="flex items-center justify-between">
|
||
|
|
<span className="text-body-small font-bold text-text-primary dark:text-white">
|
||
|
|
{t("alp.buy")}
|
||
|
|
</span>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Input Row */}
|
||
|
|
<div className="flex items-center justify-between gap-2 h-[70px]">
|
||
|
|
<div className="flex flex-col items-start justify-between flex-1 h-full">
|
||
|
|
<input
|
||
|
|
type="number"
|
||
|
|
placeholder="1,000"
|
||
|
|
value={buyAmount}
|
||
|
|
onChange={(e) => setBuyAmount(e.target.value)}
|
||
|
|
className="w-full text-left text-[32px] font-bold leading-[130%] tracking-[-0.01em] text-text-primary dark:text-white placeholder:text-[#d1d5db] dark:placeholder:text-gray-500 bg-transparent border-none outline-none [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
|
||
|
|
/>
|
||
|
|
<span className="text-body-small font-medium text-text-tertiary dark:text-gray-400">
|
||
|
|
$10,000.00 USD
|
||
|
|
</span>
|
||
|
|
</div>
|
||
|
|
<div className="flex flex-col items-end justify-between gap-1 h-full">
|
||
|
|
<button className="bg-bg-surface dark:bg-gray-600 rounded-full border border-border-normal dark:border-gray-500 px-3 h-[40px] flex items-center gap-2">
|
||
|
|
<Image
|
||
|
|
src="/component-70.svg"
|
||
|
|
alt="YTGY"
|
||
|
|
width={24}
|
||
|
|
height={24}
|
||
|
|
/>
|
||
|
|
<span className="text-body-small font-bold text-text-primary dark:text-white">YTGY</span>
|
||
|
|
<Image src="/icon8.svg" alt="" width={12} height={12} />
|
||
|
|
</button>
|
||
|
|
<span className="text-caption-tiny font-regular text-text-tertiary dark:text-gray-400">
|
||
|
|
45,230.00 USDC
|
||
|
|
</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Submit Button */}
|
||
|
|
<Button
|
||
|
|
isDisabled={!sellAmount && !buyAmount}
|
||
|
|
color="default"
|
||
|
|
className="rounded-xl h-12 px-6 text-body-small font-bold"
|
||
|
|
onPress={() => setIsConfirmModalOpen(true)}
|
||
|
|
>
|
||
|
|
{t("alp.buyUsdc")}
|
||
|
|
</Button>
|
||
|
|
|
||
|
|
{/* Rate Info */}
|
||
|
|
<div className="flex items-center justify-between px-4 py-3 bg-bg-subtle dark:bg-gray-700 rounded-xl border border-border-gray dark:border-gray-600">
|
||
|
|
<div className="flex items-center gap-2">
|
||
|
|
<span className="text-body-small font-regular text-black dark:text-white">
|
||
|
|
1 USDC = 0.99 YTGY
|
||
|
|
</span>
|
||
|
|
<span className="text-body-small font-regular text-text-tertiary dark:text-gray-400">
|
||
|
|
($1.00)
|
||
|
|
</span>
|
||
|
|
</div>
|
||
|
|
<div className="flex items-center gap-2">
|
||
|
|
<Image src="/icon7.svg" alt="" width={16} height={16} />
|
||
|
|
<span className="text-body-small font-bold text-[#dc2626] dark:text-red-400">
|
||
|
|
-$5.30
|
||
|
|
</span>
|
||
|
|
<Image src="/icon8.svg" alt="" width={12} height={12} />
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Confirm Modal */}
|
||
|
|
<ConfirmModal
|
||
|
|
isOpen={isConfirmModalOpen}
|
||
|
|
onClose={() => setIsConfirmModalOpen(false)}
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|