Skip to content
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
35 changes: 31 additions & 4 deletions app/dashboard/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ import {
currencyValues,
cryptoRates,
} from "@/components/dashboard/home";
import { useRouter } from "next/navigation";
import WithdrawOptionsMobileScreen from "@/components/dashboard/withdrawal/withdraw-options-mobile-screen";
import WithdrawalModal from "@/components/dashboard/modals/withdrawal-modal";
import { useWithdrawalStore } from "@/store/withdrawalStore";
import WithdrawalSuccessModal from "@/components/dashboard/modals/withdraw-success-modal";
import Image from "next/image";

const transactionData = [
{
Expand Down Expand Up @@ -57,6 +63,13 @@ const transactionData = [
export default function DashboardContent() {
const [balanceVisible, setBalanceVisible] = useState(true);
const [selectedCurrency, setSelectedCurrency] = useState("ETH");
const {
isMobileWithdrawOptionsOpen,
isWithdrawModalOpen,
isSuccessModalOpen,
openMobileWithdrawOptions,
} = useWithdrawalStore();
const router = useRouter();

return (
<div className="px-0 md:px-4 lg:px-0 w-full md:py-[2.25rem]">
Expand Down Expand Up @@ -119,7 +132,12 @@ export default function DashboardContent() {

<div className="md:flex space-x-4 hidden w-full">
<ActionButton icon={Download} label="Deposit" variant="primary" />
<ActionButton icon={Upload} label="Withdraw" variant="secondary" />
<ActionButton
icon={Upload}
label="Withdraw"
variant="secondary"
onClick={() => router.push("/dashboard/withdrawal")}
/>
</div>

<div className="grid grid-cols-2 gap-4 w-full">
Expand All @@ -131,10 +149,10 @@ export default function DashboardContent() {
variant="ghost"
className="flex p-[0.625rem] justify-start w-fit items-center gap-[0.5rem] rounded-lg bg-bg-dropdown hover:bg-bg-dropdown-hover"
>
<img
<Image
src={
currencyOptions.find((c) => c.code === selectedCurrency)
?.icon
?.icon || ""
}
alt={selectedCurrency}
width={16}
Expand Down Expand Up @@ -166,7 +184,13 @@ export default function DashboardContent() {

<div className="md:hidden px-2 md:px-0 grid grid-cols-3 gap-4 mt-8">
{mobileActions.map((action, index) => (
<MobileActionButton key={index} {...action} />
<MobileActionButton
key={index}
onClick={() =>
action.label === "Withdrawal" && openMobileWithdrawOptions()
}
{...action}
/>
))}
</div>

Expand All @@ -192,6 +216,9 @@ export default function DashboardContent() {
</div>
<TransactionsTable transactions={transactionData} />
</div>
{isMobileWithdrawOptionsOpen && <WithdrawOptionsMobileScreen />}
{isWithdrawModalOpen && <WithdrawalModal />}
{isSuccessModalOpen && <WithdrawalSuccessModal />}
</div>
);
}
84 changes: 84 additions & 0 deletions app/dashboard/withdrawal/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
"use client";

import WithdrawalSuccessModal from "@/components/dashboard/modals/withdraw-success-modal";
import WithdrawalModal from "@/components/dashboard/modals/withdrawal-modal";
import { useIsMobile } from "@/hooks/useIsMobile";
import { useWithdrawalStore } from "@/store/withdrawalStore";
import {
ArrowLeft,
ArrowLeftRight,
ArrowUp,
FolderSymlink,
SquareArrowOutUpRight,
} from "lucide-react";
import { useRouter } from "next/navigation";
import { useEffect } from "react";

export default function WithdrawalPage() {
const { isWithdrawModalOpen, openWithdrawModal, isSuccessModalOpen } =
useWithdrawalStore();
const router = useRouter();
const isMobile = useIsMobile();

useEffect(() => {
if (isMobile) {
router.replace("/dashboard");
openWithdrawModal();
}
}, [isMobile, openWithdrawModal, router]);

return (
<section className="p-5">
<div className="flex justify-between items-center">
<p
className="flex items-center space-x-2 cursor-pointer"
onClick={() => router.back()}
>
<ArrowLeft />
<span className="text-xl font-semibold">Withdrawal</span>
</p>
<button className="relative inline-flex items-center gap-2 rounded-full p-[1px] bg-gradient-to-r from-chart-5 to-text-link font-semibold cursor-pointer">
<span className="flex items-center gap-2 rounded-full bg-white px-4 py-2 text-black">
<span>Deposit</span>
<ArrowUp className="w-4 h-4" />
</span>
</button>
</div>{" "}
<div className="mt-10 space-y-3">
<p className="text-lg">Select a Deposit Method</p>
<div className="space-y-3">
<div
className="flex flex-col space-y-3 bg-white rounded-xl shadow-lg p-4 cursor-pointer"
onClick={() => openWithdrawModal()}
>
<p className="text-lg font-medium flex items-center space-x-3">
<FolderSymlink />
<span>Withdraw to Wallet</span>
</p>
<p className="text-sidebar-accent-foreground">
Send your crypto to any external wallet address β€” fast, secure,
and easy
</p>
<p className="font-medium text-sm">Fee: 0%</p>
</div>

<div className="flex justify-between items-start bg-white rounded-xl shadow-lg p-4 cursor-pointer">
<div className="flex flex-col space-y-3">
<p className="text-lg font-medium flex items-center space-x-3">
<ArrowLeftRight />
<span>Sell for Fiat (via MoonPay)</span>
</p>
<p className="text-sidebar-accent-foreground">
Sell your crypto and receive fiat into your bank or card account
</p>
<p className="font-medium text-sm">Fee: 0%</p>
</div>
<SquareArrowOutUpRight />
</div>
</div>
</div>
{isWithdrawModalOpen && <WithdrawalModal />}
{isSuccessModalOpen && <WithdrawalSuccessModal />}
</section>
);
}
5 changes: 4 additions & 1 deletion components/dashboard/home/action-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@ import React from "react";
import { Button } from "@/components/ui/button";

interface ActionButtonProps {
icon: React.ComponentType<any>;
icon: React.ComponentType<React.SVGProps<SVGSVGElement>>;
label: string;
variant?: "primary" | "secondary";
onClick?: () => void;
}

export function ActionButton({
icon: Icon,
label,
variant = "primary",
onClick,
}: ActionButtonProps) {
const isPrimary = variant === "primary";
const variantClasses = isPrimary
Expand All @@ -20,6 +22,7 @@ export function ActionButton({
return (
<Button
className={`flex w-[12.346rem] h-[3.175rem] p-[0.565rem] justify-center items-center gap-[0.706rem] rounded-[0.565rem] font-medium text-[1.129rem] leading-[140%] tracking-[0.542px] opacity-90 ${variantClasses}`}
onClick={onClick}
>
<Icon className="h-6 w-6" />
{label}
Expand Down
3 changes: 2 additions & 1 deletion components/dashboard/home/currency-dropdown-item.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from "react";
import { DropdownMenuItem } from "@/components/ui/dropdown-menu";
import Image from "next/image";

export interface CurrencyOption {
code: string;
Expand All @@ -19,7 +20,7 @@ export function CurrencyDropdownItem({
return (
<DropdownMenuItem onClick={onClick}>
<div className="flex items-center space-x-2">
<img src={currency.icon} alt={currency.code} width={16} height={16} />
<Image src={currency.icon} alt={currency.code} width={16} height={16} />
<span>
{currency.code} - {currency.name}
</span>
Expand Down
3 changes: 3 additions & 0 deletions components/dashboard/home/mobile-action-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,20 @@ interface MobileActionButtonProps {
icon: string;
label: string;
alt: string;
onClick?: () => void;
}

export function MobileActionButton({
icon,
label,
alt,
onClick,
}: MobileActionButtonProps) {
return (
<Button
variant="outline"
className="flex px-1 h-17 py-2 flex-col items-center gap-1 flex-1 rounded-lg bg-white text-black text-xs font-medium leading-[140%]"
onClick={onClick}
>
<div className="h-7 w-7 rounded-2xl bg-bg-icon-container flex items-center justify-center">
<Image src={icon} alt={alt} width={16} height={16} />
Expand Down
42 changes: 42 additions & 0 deletions components/dashboard/modals/withdraw-success-modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { useWithdrawalStore } from "@/store/withdrawalStore";
import Image from "next/image";

export default function WithdrawalSuccessModal() {
const { closeSuccessModal } = useWithdrawalStore();
return (
<div
className="fixed inset-0 bg-black/50 flex items-center justify-center p-4 z-50"
onClick={closeSuccessModal}
>
<div
className="bg-white rounded-2xl w-full max-w-md mx-auto shadow-2xl overflow-hidden"
onClick={(e) => e.stopPropagation()}
>
<div className="flex flex-col justify-center items-center bg-gradient-to-br from-[#FFE79C]/70 from-20% to-[#A0C3FD]/70 to-80% px-6 py-5 text-center w-[90%] mx-auto mt-5 rounded-xl">
<Image src="/green-tick.svg" alt="Success" width={50} height={50} />

<h2 className="text-lg font-medium text-gray-700 mb-6">
Withdrawal Successful
</h2>

<div className="text-3xl font-bold text-gray-900">
-100,000
<span className="text-xl font-medium text-gray-600">NGN</span>
</div>
</div>

<div className="p-6 flex space-x-3">
<button className="flex-1 bg-[#F3C740] font-medium py-3 rounded-lg transition-colors">
View details
</button>
<button
className="flex-1 bg-gray-100 hover:bg-gray-200 text-gray-700 font-medium py-3 rounded-lg transition-colors border border-gray-200"
onClick={closeSuccessModal}
>
Close
</button>
</div>
</div>
</div>
);
}
Loading