diff --git a/src/pages/finance/lib/type.ts b/src/pages/finance/lib/type.ts
index df51f29..64a41ee 100644
--- a/src/pages/finance/lib/type.ts
+++ b/src/pages/finance/lib/type.ts
@@ -28,6 +28,12 @@ export interface UserOrderData {
tour_name: string;
}[];
total_income: string;
+ awaiting_payments: string;
+ awaiting_payments_count: string;
+ confirmed_order: string;
+ pending_confirmation: string;
+ completed_order: string;
+ cancelled_order: string;
};
};
}
diff --git a/src/pages/finance/ui/Finance.tsx b/src/pages/finance/ui/Finance.tsx
index a48c835..44bdf13 100644
--- a/src/pages/finance/ui/Finance.tsx
+++ b/src/pages/finance/ui/Finance.tsx
@@ -8,32 +8,177 @@ import { Button } from "@/shared/ui/button";
import { useQuery } from "@tanstack/react-query";
import {
AlertTriangle,
+ CheckCircle,
+ ChevronLeft,
+ ChevronRight,
+ Clock,
CreditCard,
DollarSign,
Eye,
- Hotel,
Loader2,
MapPin,
Plane,
TrendingUp,
Users,
+ XCircle,
} from "lucide-react";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
+type Purchase = {
+ id: number;
+ userName: string;
+ userPhone: string;
+ tourName: string;
+ tourId: number;
+ agencyName: string;
+ agencyId: number;
+ destination: string;
+ travelDate: string;
+ amount: number;
+ paymentStatus: "paid" | "pending" | "cancelled" | "refunded";
+ purchaseDate: string;
+};
+
+const mockPurchases: Purchase[] = [
+ {
+ id: 1,
+ userName: "Aziza Karimova",
+ userPhone: "+998 90 123 45 67",
+ tourName: "Dubai Luxury Tour",
+ tourId: 1,
+ agencyName: "Silk Road Travel",
+ agencyId: 1,
+ destination: "Dubai, UAE",
+ travelDate: "2025-11-10",
+ amount: 1500000,
+ paymentStatus: "paid",
+ purchaseDate: "2025-10-10",
+ },
+ {
+ id: 2,
+ userName: "Sardor Rahimov",
+ userPhone: "+998 91 234 56 78",
+ tourName: "Bali Adventure Package",
+ tourId: 2,
+ agencyName: "Silk Road Travel",
+ agencyId: 1,
+ destination: "Bali, Indonesia",
+ travelDate: "2025-11-15",
+ amount: 1800000,
+ paymentStatus: "paid",
+ purchaseDate: "2025-10-12",
+ },
+ {
+ id: 3,
+ userName: "Nilufar Toshmatova",
+ userPhone: "+998 93 345 67 89",
+ tourName: "Dubai Luxury Tour",
+ tourId: 1,
+ agencyName: "Silk Road Travel",
+ agencyId: 1,
+ destination: "Dubai, UAE",
+ travelDate: "2025-11-20",
+ amount: 1500000,
+ paymentStatus: "pending",
+ purchaseDate: "2025-10-14",
+ },
+ {
+ id: 4,
+ userName: "Jamshid Alimov",
+ userPhone: "+998 94 456 78 90",
+ tourName: "Istanbul Express Tour",
+ tourId: 3,
+ agencyName: "Orient Express",
+ agencyId: 3,
+ destination: "Istanbul, Turkey",
+ travelDate: "2025-11-05",
+ amount: 1200000,
+ paymentStatus: "cancelled",
+ purchaseDate: "2025-10-08",
+ },
+ {
+ id: 5,
+ userName: "Madina Yusupova",
+ userPhone: "+998 97 567 89 01",
+ tourName: "Paris Romantic Getaway",
+ tourId: 4,
+ agencyName: "Euro Travels",
+ agencyId: 2,
+ destination: "Paris, France",
+ travelDate: "2025-12-01",
+ amount: 2200000,
+ paymentStatus: "paid",
+ purchaseDate: "2025-10-16",
+ },
+];
+
export default function FinancePage() {
const { t } = useTranslation();
+ const [currentPage, setCurrentPage] = useState(1);
const [tab, setTab] = useState<"bookings" | "agencies">("bookings");
const [filterStatus, setFilterStatus] = useState<
"all" | "paid" | "pending" | "cancelled" | "refunded"
>("all");
const { data, isLoading, isError, refetch } = useQuery({
- queryKey: ["list_order_user"],
- queryFn: () => getAllOrder({ page: 1, page_size: 10 }),
+ queryKey: ["list_order_user", currentPage],
+ queryFn: () => getAllOrder({ page: currentPage, page_size: 10 }),
});
+ const stats = [
+ {
+ title: t("Jami daromad"),
+ value: data?.data.data.results.total_income ?? "0",
+ description: t("Yakunlangan bandlovlardan"),
+ icon: ,
+ color: "text-green-400",
+ },
+ {
+ title: t("Kutilayotgan to‘lovlar"),
+ value: data?.data.data.results.awaiting_payments ?? "0",
+ description: t("Tasdiqlash kutilmoqda"),
+ icon: ,
+ color: "text-yellow-400",
+ },
+ {
+ title: t("Kutilayotgan to‘lovlar soni"),
+ value: data?.data.data.results.awaiting_payments_count ?? "0",
+ description: t("To‘lov kutilayotgan buyurtmalar soni"),
+ icon: ,
+ color: "text-orange-400",
+ },
+ {
+ title: t("Tasdiqlangan buyurtmalar"),
+ value: data?.data.data.results.confirmed_order ?? "0",
+ description: t("Tasdiqlangan bandlovlar soni"),
+ icon: ,
+ color: "text-blue-400",
+ },
+ {
+ title: t("Kutilayotgan tasdiqlar"),
+ value: data?.data.data.results.pending_confirmation ?? "0",
+ description: t("Hali tasdiqlanmagan bandlovlar"),
+ icon: ,
+ color: "text-purple-400",
+ },
+ {
+ title: t("Yakunlangan buyurtmalar"),
+ value: data?.data.data.results.completed_order ?? "0",
+ description: t("Muvaffaqiyatli yakunlangan buyurtmalar"),
+ icon: ,
+ color: "text-emerald-400",
+ },
+ {
+ title: t("Bekor qilingan buyurtmalar"),
+ value: data?.data.data.results.cancelled_order ?? "0",
+ description: t("Bekor qilingan bandlovlar soni"),
+ icon: ,
+ color: "text-red-400",
+ },
+ ];
+
const getStatusBadge = (status: OrderStatus["order_status"]) => {
const base =
"px-3 py-1 rounded-full text-sm font-medium inline-flex items-center gap-2";
@@ -120,6 +265,26 @@ export default function FinancePage() {
);
}
+ const agencies = Array.from(
+ new Set(mockPurchases.map((p) => p.agencyId)),
+ ).map((id) => {
+ const agencyPurchases = mockPurchases.filter((p) => p.agencyId === id);
+ return {
+ id,
+ name: agencyPurchases[0].agencyName,
+ totalPaid: agencyPurchases
+ .filter((p) => p.paymentStatus === "paid")
+ .reduce((sum, p) => sum + p.amount, 0),
+ pending: agencyPurchases
+ .filter((p) => p.paymentStatus === "pending")
+ .reduce((sum, p) => sum + p.amount, 0),
+ purchaseCount: agencyPurchases.length,
+ destinations: Array.from(
+ new Set(agencyPurchases.map((p) => p.destination)),
+ ),
+ };
+ });
+
return (
@@ -201,70 +366,24 @@ export default function FinancePage() {
{/* Stats */}
-
-
-
-
- {t("Jami daromad")}
+
+ {stats.map((item, index) => (
+
+
+
{item.title}
+ {item.icon}
+
+
+ {Number(item.value).toLocaleString()}
-
-
-
- {/* {formatPrice(totalRevenue, true)} */}
-
-
- {t("Yakunlangan bandlovlardan")}
-
-
-
-
-
- {t("Kutilayotgan to‘lovlar")}
+
+ {item.description}
-
-
- {/* {formatPrice(pendingRevenue, true)} */}
-
-
- {t("Tasdiqlash kutilmoqda")}
-
-
-
-
-
- {t("Tasdiqlangan bandlovlar")}
-
-
-
-
- {/* {
- filteredPurchases.filter((p) => p.paymentStatus === "paid")
- .length
- } */}
-
-
- {t("Tasdiqlangan bandlovlar")}
-
-
-
-
-
- {t("Kutilayotgan bandlovlar")}
-
-
-
-
- {/* {
- filteredPurchases.filter(
- (p) => p.paymentStatus === "pending",
- ).length
- } */}
-
-
- {t("Kutilayotgan to‘lovlar")}
-
-
+ ))}
{/* Booking Cards */}
@@ -321,10 +440,45 @@ export default function FinancePage() {
))}
+
+
+
+ {[...Array(data?.data.data.total_pages)].map((_, i) => (
+
+ ))}
+
+
+
>
)}
- {/* {tab === "agencies" && (
+ {tab === "agencies" && (
<>
Partner Agencies
@@ -380,7 +534,7 @@ export default function FinancePage() {
))}
>
- )} */}
+ )}
);
diff --git a/src/pages/finance/ui/FinanceDetailUsers.tsx b/src/pages/finance/ui/FinanceDetailUsers.tsx
index 7853f40..2f91d9e 100644
--- a/src/pages/finance/ui/FinanceDetailUsers.tsx
+++ b/src/pages/finance/ui/FinanceDetailUsers.tsx
@@ -61,11 +61,12 @@ export default function FinanceDetailUser() {
};
}) => updateDetailOrder({ body, id }),
onSuccess: () => {
+ queryClient.refetchQueries({ queryKey: ["detail_order"] });
+ queryClient.refetchQueries({ queryKey: ["list_order_user"] });
toast.success(t("Status muvaffaqiyatli yangilandi"), {
richColors: true,
position: "top-center",
});
- queryClient.invalidateQueries({ queryKey: ["detail_order"] });
},
onError: () => {
toast.error(t("Statusni yangilashda xatolik yuz berdi"), {
diff --git a/src/pages/support/ui/SupportTours.tsx b/src/pages/support/ui/SupportTours.tsx
index 9b5170c..d689008 100644
--- a/src/pages/support/ui/SupportTours.tsx
+++ b/src/pages/support/ui/SupportTours.tsx
@@ -89,32 +89,6 @@ const SupportTours = () => {
});
};
- if (isLoading) {
- return (
-
-
-
{t("Ma'lumotlar yuklanmoqda...")}
-
- );
- }
-
- if (isError) {
- return (
-
-
-
- {t("Ma'lumotlarni yuklashda xatolik yuz berdi.")}
-
-
-
- );
- }
-
return (
@@ -141,76 +115,100 @@ const SupportTours = () => {
))}
-
- {/* Cards */}
-
- {data && data.data.data.results.length === 0 ? (
-
-
{t("Natija topilmadi")}
-
- ) : (
- data?.data.data.results.map((req) => (
-
-
-
-
-
- {req.name}
-
+ {isError ? (
+
+
+
+ {t("Ma'lumotlarni yuklashda xatolik yuz berdi.")}
+
+
+
+ ) : (
+ <>
+ {isLoading ? (
+
+
+
+ {t("Ma'lumotlar yuklanmoqda...")}
+
+
+ ) : (
+
+ {data && data.data.data.results.length === 0 ? (
+
+
{t("Natija topilmadi")}
-
-
- {req.status === "pending" ? t("Kutilmoqda") : t("done")}
-
-
-
-
- {req.travel_agency !== null ? (
-
- {t("Agentlikka tegishli")}
-
- ) : (
-
- {t("Sayt bo'yicha")}
-
- )}
-
-
- {formatPhone(req.phone_number)}
-
-
-
-
-
-
-
- ))
- )}
-
+
+
+
+
+ {req.name}
+
+
+
+
+ {req.status === "pending" ? t("Kutilmoqda") : t("done")}
+
+
+
+
+ {req.travel_agency !== null ? (
+
+ {t("Agentlikka tegishli")}
+
+ ) : (
+
+ {t("Sayt bo'yicha")}
+
+ )}
+
+
+ {formatPhone(req.phone_number)}
+
+
+
+
+
+
+
+ ))
+ )}
+
+ )}
+ >
+ )}
{/* Detail Modal */}