Vitron-Front/app/routes/profile.wallet._index.tsx
2026-04-29 01:44:16 +03:30

210 lines
6.9 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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