210 lines
6.9 KiB
TypeScript
210 lines
6.9 KiB
TypeScript
import type { MetaFunction } from "@remix-run/node";
|
||
import { Plus } from "lucide-react";
|
||
import { useState } from "react";
|
||
import ProfilePagesHeader from "../components/ProfilePagesHeader";
|
||
import {
|
||
useServiceGetWallet,
|
||
useServiceCreatePayoutRequest,
|
||
} from "../utils/RequestHandler";
|
||
import { Button } from "../components/ui/button";
|
||
import { Dialog, DialogContent, DialogOverlay } from "../components/ui/dialog";
|
||
import AppInput from "../components/AppInput";
|
||
import { useToast } from "../hooks/use-toast";
|
||
import { getPersianTextOfPrice } from "~/utils/helpers";
|
||
import UiProvider from "~/components/UiProvider";
|
||
|
||
export const meta: MetaFunction = () => {
|
||
return [
|
||
{ title: "کیف پول - ویترون" },
|
||
{
|
||
name: "description",
|
||
content:
|
||
"مدیریت کیف پول و موجودی حساب کاربری شما در ویترون. افزایش موجودی، پیگیری تراکنشها و مدیریت امور مالی.",
|
||
},
|
||
{
|
||
name: "keywords",
|
||
content:
|
||
"کیف پول، موجودی، افزایش موجودی، تراکنش، پرداخت، ویترون، پروفایل کاربری",
|
||
},
|
||
{ name: "robots", content: "noindex, follow" },
|
||
{ property: "og:title", content: "کیف پول - ویترون" },
|
||
{
|
||
property: "og:description",
|
||
content:
|
||
"مدیریت کیف پول و موجودی حساب کاربری شما در ویترون. افزایش موجودی، پیگیری تراکنشها و مدیریت امور مالی.",
|
||
},
|
||
{ property: "og:type", content: "website" },
|
||
{ name: "twitter:card", content: "summary" },
|
||
{ name: "twitter:title", content: "کیف پول - ویترون" },
|
||
{
|
||
name: "twitter:description",
|
||
content:
|
||
"مدیریت کیف پول و موجودی حساب کاربری شما در ویترون. افزایش موجودی، پیگیری تراکنشها و مدیریت امور مالی.",
|
||
},
|
||
];
|
||
};
|
||
|
||
export default function Locaton() {
|
||
const [isOpen, setIsOpen] = useState(false);
|
||
const [amount, setAmount] = useState("");
|
||
|
||
return (
|
||
<div className="flex flex-col gap-6 w-full items-center">
|
||
<ProfilePagesHeader title="کیف پول" />
|
||
<MainContent />
|
||
<Button
|
||
className="fixed bottom-16 z-10"
|
||
size={"xl"}
|
||
variant="dark"
|
||
onClick={() => setIsOpen(true)}
|
||
>
|
||
<Plus className="text-WHITE size-6" />
|
||
افزایش موجودی
|
||
</Button>
|
||
<AddFundsDialog
|
||
isOpen={isOpen}
|
||
onClose={() => setIsOpen(false)}
|
||
amount={amount}
|
||
setAmount={setAmount}
|
||
/>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
const AddFundsDialog = ({
|
||
isOpen,
|
||
onClose,
|
||
amount,
|
||
setAmount,
|
||
}: {
|
||
isOpen: boolean;
|
||
onClose: () => void;
|
||
amount: string;
|
||
setAmount: (value: string) => void;
|
||
}) => {
|
||
const { toast } = useToast();
|
||
const createPayoutRequest = useServiceCreatePayoutRequest();
|
||
|
||
const handleSubmit = async (e: React.FormEvent) => {
|
||
e.preventDefault();
|
||
try {
|
||
const response = await createPayoutRequest.mutateAsync({
|
||
amount,
|
||
transaction_type: "deposit",
|
||
});
|
||
|
||
if (response?.paymentUrl) {
|
||
window.location.href = response.paymentUrl;
|
||
} else {
|
||
toast({
|
||
title: "خطا در پرداخت",
|
||
description: "لینک پرداخت دریافت نشد. لطفا دوباره تلاش کنید.",
|
||
variant: "destructive",
|
||
});
|
||
}
|
||
} catch (error) {
|
||
toast({
|
||
title: "خطا در ثبت درخواست",
|
||
description:
|
||
"متاسفانه مشکلی در ثبت درخواست پیش آمده است. لطفا دوباره تلاش کنید.",
|
||
variant: "destructive",
|
||
});
|
||
}
|
||
};
|
||
|
||
return (
|
||
<Dialog open={isOpen} onOpenChange={onClose}>
|
||
<DialogOverlay />
|
||
<DialogContent className="p-4 bg-WHITE rounded-[15px] w-[calc(100%-40px)]">
|
||
<div className="flex flex-col gap-10">
|
||
<div className="flex flex-col gap-3 items-center w-full">
|
||
<Plus className="text-primary text-6" />
|
||
<p className="text-B12 font-bold mt-1">افزایش موجودی</p>
|
||
<AppInput
|
||
inputTitle=""
|
||
inputValue={amount}
|
||
inputPlaceholder="مبلغ را وارد کنید"
|
||
inputOnChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||
setAmount(e.target.value)
|
||
}
|
||
type="number"
|
||
inputDir={amount ? "ltr" : "rtl"}
|
||
/>
|
||
<p className="text-B12 w-full font-bold">
|
||
{getPersianTextOfPrice(amount)}
|
||
</p>
|
||
</div>
|
||
<div className="flex flex-row gap-6 w-full">
|
||
<Button
|
||
className="w-[100%]"
|
||
size={"sm"}
|
||
variant="outline"
|
||
onClick={() => onClose()}
|
||
>
|
||
انصراف
|
||
</Button>
|
||
<Button
|
||
disabled={createPayoutRequest.isPending}
|
||
className="w-[100%]"
|
||
size={"sm"}
|
||
variant="dark"
|
||
onClick={handleSubmit}
|
||
>
|
||
{createPayoutRequest.isPending ? (
|
||
<>
|
||
<div className="relative w-5 h-5 mr-2">
|
||
<div className="absolute top-0 left-0 w-full h-full border-2 border-t-primary border-r-transparent border-b-transparent border-l-transparent rounded-full animate-spin"></div>
|
||
<div
|
||
className="absolute top-0.5 left-0.5 w-4 h-4 border-2 border-t-transparent border-r-primary border-b-transparent border-l-transparent rounded-full animate-spin"
|
||
style={{
|
||
animationDirection: "reverse",
|
||
animationDuration: "0.7s",
|
||
}}
|
||
></div>
|
||
</div>
|
||
در حال ثبت...
|
||
</>
|
||
) : (
|
||
"ثبت درخواست"
|
||
)}
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
</DialogContent>
|
||
</Dialog>
|
||
);
|
||
};
|
||
|
||
const MainContent = () => {
|
||
const {
|
||
data: walletData,
|
||
isFetching: isFetchingWallet,
|
||
isError,
|
||
refetch,
|
||
} = useServiceGetWallet();
|
||
|
||
const formatBalance = (balance: string) => {
|
||
return new Intl.NumberFormat("fa-IR").format(parseInt(balance));
|
||
};
|
||
|
||
return (
|
||
<UiProvider
|
||
isLoading={isFetchingWallet}
|
||
isError={isError}
|
||
isEmpty={false}
|
||
onRetry={refetch}
|
||
type="wallet"
|
||
>
|
||
<div className="flex flex-col gap-6 items-center mt-[100px]">
|
||
<p className="text-R16 text-BLACK2">موجودی شما (تومان): </p>
|
||
<p className="text-B24 font-bold">
|
||
{walletData ? formatBalance(walletData.balance || "") : "۰"}
|
||
</p>
|
||
<p className="text-R12 text-GRAY mt-8">
|
||
با افزایش موجودی کیف پول، از امکان خرید قسطی استفاده کن!
|
||
</p>
|
||
</div>
|
||
</UiProvider>
|
||
);
|
||
};
|