166 lines
6.1 KiB
TypeScript
166 lines
6.1 KiB
TypeScript
import { Sun, Waves, Loader2 } from "lucide-react";
|
||
import HeaderWithSupport from "../components/HeaderWithSupport";
|
||
import PersianDatePicker from "../components/PersianDatePicker";
|
||
import { useEffect, useState } from "react";
|
||
import { useSearchParams, useNavigate } from "react-router-dom";
|
||
import { formatPrice, safeGoBack } from "../utils/helpers";
|
||
import { useServiceGetReport } from "../requestHandler/use-wallet-hooks";
|
||
import jMoment from "moment-jalaali";
|
||
import { MetaFunction } from "@remix-run/node";
|
||
|
||
export default function Reports() {
|
||
const navigate = useNavigate();
|
||
const handleBack = () => {
|
||
safeGoBack(navigate);
|
||
};
|
||
const [fromDate, setFromDate] = useState<string>("");
|
||
const [toDate, setToDate] = useState<string>("");
|
||
const [searchParams, setSearchParams] = useSearchParams();
|
||
|
||
// Convert Persian date to Gregorian ISO string
|
||
const convertPersianToGregorian = (persianDate: string): string => {
|
||
// Persian date format is expected to be YYYY/MM/DD
|
||
const [year, month, day] = persianDate.split("/");
|
||
const jMomentDate = jMoment(`${year}/${month}/${day}`, "jYYYY/jM/jD");
|
||
return jMomentDate.format("YYYY-MM-DD");
|
||
};
|
||
|
||
// Get filters for API
|
||
const getFilters = () => {
|
||
const filters: { fromDate?: string; toDate?: string } = {};
|
||
|
||
if (fromDate) {
|
||
try {
|
||
filters.fromDate = convertPersianToGregorian(fromDate);
|
||
} catch (error) {
|
||
console.error("Error converting fromDate:", error);
|
||
}
|
||
}
|
||
|
||
if (toDate) {
|
||
try {
|
||
filters.toDate = convertPersianToGregorian(toDate);
|
||
} catch (error) {
|
||
console.error("Error converting toDate:", error);
|
||
}
|
||
}
|
||
|
||
return Object.keys(filters).length > 0 ? filters : undefined;
|
||
};
|
||
|
||
// Fetch report data
|
||
const { data: reportData, isLoading } = useServiceGetReport(getFilters());
|
||
|
||
useEffect(() => {
|
||
const params: Record<string, string> = {};
|
||
if (fromDate) params.fromDate = fromDate;
|
||
if (toDate) params.toDate = toDate;
|
||
setSearchParams(params, { replace: true });
|
||
}, [fromDate, toDate, setSearchParams]);
|
||
|
||
return (
|
||
<div className="bg-WHITE">
|
||
<HeaderWithSupport title="گزارش مالی" onBack={handleBack} />
|
||
<div className="bg-WHITE p-4 w-full flex gap-2 items-center">
|
||
<div className="w-full">
|
||
<PersianDatePicker
|
||
value={fromDate}
|
||
onChange={setFromDate}
|
||
placeholder="از تاریخ"
|
||
label=""
|
||
/>
|
||
</div>
|
||
|
||
{/* To Date */}
|
||
<div className="w-full">
|
||
<PersianDatePicker
|
||
value={toDate}
|
||
onChange={setToDate}
|
||
placeholder="تا تاریخ"
|
||
label=""
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div className="w-full px-4">
|
||
{isLoading ? (
|
||
<div className="flex items-center justify-center py-8">
|
||
<Loader2 className="w-8 h-8 animate-spin" />
|
||
</div>
|
||
) : reportData ? (
|
||
<>
|
||
<div className="w-full py-4 flex flex-col border-b gap-6">
|
||
<div className="w-full flex flex-col gap-2">
|
||
<div className="flex gap-2">
|
||
<Waves size={20} className="text-blue-500" />
|
||
<p className="text-B14 font-bold">میزان فروش کل (تومان):</p>
|
||
</div>
|
||
<p className="text-R12 text-GRAY">
|
||
جمع مبلغ پرداختشده توسط خریداران
|
||
</p>
|
||
<p className="text-B18 font-bold text-BLACK">
|
||
{formatPrice(reportData.totalSales.toString())}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div className="w-full py-4 flex border-b flex-col gap-6">
|
||
<div className="w-full flex flex-col gap-2">
|
||
<div className="flex gap-2">
|
||
<Sun size={20} className="text-blue-500" />
|
||
<p className="text-B14 font-bold">
|
||
وضعیت تسویه حساب (تومان):
|
||
</p>
|
||
</div>
|
||
<p className="text-R12 text-GRAY">
|
||
وضعیت واریز درآمد در این بازه
|
||
</p>
|
||
<p className="text-B14 font-bold">
|
||
تسویه شده: {formatPrice(reportData.totalSettled.toString())}
|
||
</p>
|
||
<p className="text-B14 text-GRAY font-bold">
|
||
در انتظار پرداخت:{" "}
|
||
{formatPrice(reportData.pendingSettlement.toString())}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</>
|
||
) : (
|
||
<div className="flex flex-col items-center justify-center py-8 text-GRAY">
|
||
<p className="text-B16">خطا در بارگذاری گزارش</p>
|
||
<p className="text-R12 mt-2">لطفا مجددا تلاش کنید</p>
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
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:
|
||
"مدیریت و مشاهده تمام گزارش مالی در فروشگاه شما. فیلتر بر اساس وضعیت و جستجو در گزارش مالی.",
|
||
},
|
||
];
|
||
};
|