447 lines
14 KiB
TypeScript
447 lines
14 KiB
TypeScript
"use client";
|
|
|
|
import {
|
|
countryList,
|
|
getAllAmenities,
|
|
hotelBadge,
|
|
hotelFeature,
|
|
hotelFeatureType,
|
|
hotelMealList,
|
|
hotelTarif,
|
|
hotelTransport,
|
|
hotelType,
|
|
regionList,
|
|
} from "@/pages/tours/lib/api";
|
|
import Amenities from "@/pages/tours/ui/Amenities";
|
|
import BadgeTable from "@/pages/tours/ui/BadgeTable";
|
|
import CountryTable from "@/pages/tours/ui/CountryTable";
|
|
import FeaturesTable from "@/pages/tours/ui/FeaturesTable";
|
|
import FeaturesTableType from "@/pages/tours/ui/FeaturesTableType";
|
|
import HotelType from "@/pages/tours/ui/HotelType";
|
|
import MealTable from "@/pages/tours/ui/MealTable";
|
|
import RegionTable from "@/pages/tours/ui/RegionTable";
|
|
import TarifTable from "@/pages/tours/ui/TarifTable";
|
|
import TransportTable from "@/pages/tours/ui/TransportTable";
|
|
import { Button } from "@/shared/ui/button";
|
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/shared/ui/tabs";
|
|
|
|
import { useQuery } from "@tanstack/react-query";
|
|
import { AlertTriangle, Loader2 } from "lucide-react";
|
|
import React, { useState } from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
import { useNavigate, useSearchParams } from "react-router-dom";
|
|
|
|
// Error Component
|
|
const ErrorDisplay: React.FC<{ message: string; onRetry: () => void }> = ({
|
|
message,
|
|
onRetry,
|
|
}) => {
|
|
const { t } = useTranslation();
|
|
return (
|
|
<div className="flex flex-col items-center justify-center min-h-[300px] bg-slate-800/50 rounded-lg text-center text-white gap-4 p-6">
|
|
<AlertTriangle className="w-10 h-10 text-red-500" />
|
|
<p className="text-lg">{message}</p>
|
|
<Button
|
|
onClick={onRetry}
|
|
className="bg-gradient-to-r from-blue-600 to-cyan-600 text-white rounded-lg px-5 py-2 hover:opacity-90"
|
|
>
|
|
{t("Qayta urinish")}
|
|
</Button>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
// Loading Component
|
|
const LoadingDisplay: React.FC<{ message?: string }> = ({ message }) => {
|
|
const { t } = useTranslation();
|
|
return (
|
|
<div className="flex flex-col items-center justify-center min-h-[300px] bg-slate-800/50 rounded-lg text-white gap-4">
|
|
<Loader2 className="w-10 h-10 animate-spin text-cyan-400" />
|
|
<p className="text-slate-400">
|
|
{message || t("Ma'lumotlar yuklanmoqda...")}
|
|
</p>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
const ToursSetting: React.FC = () => {
|
|
const { t } = useTranslation();
|
|
const [searchParams] = useSearchParams();
|
|
const [activeTab, setActiveTab] = useState("badge");
|
|
const [featureId, setFeatureId] = useState<number | null>(null);
|
|
const [countryId, setCountryId] = useState<number | null>(null);
|
|
const navigate = useNavigate();
|
|
|
|
const page = parseInt(searchParams.get("page") || "1", 10);
|
|
const pageSize = parseInt(searchParams.get("pageSize") || "10", 10);
|
|
|
|
const { data, isLoading, isError, refetch } = useQuery({
|
|
queryKey: ["all_badge", page, pageSize],
|
|
queryFn: () => hotelBadge({ page, page_size: pageSize }),
|
|
select: (res) => res.data.data,
|
|
});
|
|
|
|
const pageTarif = parseInt(searchParams.get("pageTarif") || "1", 10);
|
|
const pageSizeTarif = parseInt(searchParams.get("pageTarifSize") || "10", 10);
|
|
|
|
const {
|
|
data: tarifData,
|
|
isLoading: tarifLoad,
|
|
isError: tarifError,
|
|
refetch: tarifRef,
|
|
} = useQuery({
|
|
queryKey: ["all_tarif", pageTarif, pageSizeTarif],
|
|
queryFn: () => hotelTarif({ page: pageTarif, page_size: pageSizeTarif }),
|
|
select: (res) => res.data.data,
|
|
});
|
|
|
|
const pageTransport = parseInt(searchParams.get("pageTransport") || "1", 10);
|
|
const pageSizeTransport = parseInt(
|
|
searchParams.get("pageTransportSize") || "10",
|
|
10,
|
|
);
|
|
|
|
const {
|
|
data: transportData,
|
|
isLoading: transportLoad,
|
|
isError: transportError,
|
|
refetch: transportRef,
|
|
} = useQuery({
|
|
queryKey: ["all_transport", pageTransport, pageSizeTransport],
|
|
queryFn: () =>
|
|
hotelTransport({ page: pageTransport, page_size: pageSizeTransport }),
|
|
select: (res) => res.data.data,
|
|
});
|
|
|
|
const pageType = parseInt(searchParams.get("pageType") || "1", 10);
|
|
const pageSizeType = parseInt(searchParams.get("pageTypeSize") || "10", 10);
|
|
|
|
const {
|
|
data: typeData,
|
|
isLoading: typeLoad,
|
|
isError: typeError,
|
|
refetch: typeRef,
|
|
} = useQuery({
|
|
queryKey: ["all_type", pageType, pageSizeType],
|
|
queryFn: () => hotelType({ page: pageType, page_size: pageSizeType }),
|
|
select: (res) => res.data.data,
|
|
});
|
|
|
|
const pageCountry = parseInt(searchParams.get("pageCountry") || "1", 10);
|
|
const pageSizeCountry = parseInt(
|
|
searchParams.get("pageSizeCountry") || "10",
|
|
10,
|
|
);
|
|
|
|
const {
|
|
data: countryData,
|
|
isLoading: countryLoad,
|
|
isError: countryError,
|
|
refetch: countryRef,
|
|
} = useQuery({
|
|
queryKey: ["all_country", pageCountry, pageSizeCountry],
|
|
queryFn: () =>
|
|
countryList({ page: pageCountry, page_size: pageSizeCountry }),
|
|
select: (res) => res.data.data,
|
|
});
|
|
|
|
const pageRegion = parseInt(searchParams.get("pageRegion") || "1", 10);
|
|
const pageSizeRegion = parseInt(
|
|
searchParams.get("pageSizeRegion") || "10",
|
|
10,
|
|
);
|
|
|
|
const {
|
|
data: regionData,
|
|
isLoading: regionLoad,
|
|
isError: regionError,
|
|
refetch: regionRef,
|
|
} = useQuery({
|
|
queryKey: ["all_region", pageRegion, pageSizeRegion, countryId],
|
|
queryFn: () =>
|
|
regionList({
|
|
page: pageRegion,
|
|
page_size: pageSizeRegion,
|
|
country: countryId!,
|
|
}),
|
|
select: (res) => res.data.data,
|
|
enabled: !!countryId,
|
|
});
|
|
|
|
const pageFeature = parseInt(searchParams.get("pageFeature") || "1", 10);
|
|
const pageSizeFeature = parseInt(
|
|
searchParams.get("pageSizeFeature") || "10",
|
|
10,
|
|
);
|
|
|
|
const {
|
|
data: featureData,
|
|
isLoading: featureLoad,
|
|
isError: featureError,
|
|
refetch: featureRef,
|
|
} = useQuery({
|
|
queryKey: ["all_feature", pageFeature, pageSizeFeature],
|
|
queryFn: () =>
|
|
hotelFeature({ page: pageFeature, page_size: pageSizeFeature }),
|
|
select: (res) => res.data.data,
|
|
});
|
|
|
|
const {
|
|
data: featureTypeData,
|
|
isLoading: featureTypeLoad,
|
|
isError: featureTypeError,
|
|
refetch: featureTypeRef,
|
|
} = useQuery({
|
|
queryKey: ["all_feature_type", pageFeature, pageSizeFeature, featureId],
|
|
queryFn: () =>
|
|
hotelFeatureType({
|
|
page: pageFeature,
|
|
page_size: pageSizeFeature,
|
|
feature_type: featureId!,
|
|
}),
|
|
select: (res) => res.data.data,
|
|
enabled: !!featureId,
|
|
});
|
|
|
|
const pageAmenities = parseInt(searchParams.get("pageAmenities") || "1", 10);
|
|
const pageSizeAmenities = parseInt(
|
|
searchParams.get("pageSizeAmenities") || "10",
|
|
10,
|
|
);
|
|
|
|
const {
|
|
data: amenitiesData,
|
|
isLoading: amenitiesLoad,
|
|
isError: amenitiesError,
|
|
refetch: amenitiesRef,
|
|
} = useQuery({
|
|
queryKey: ["all_amenities", pageAmenities, pageSizeAmenities],
|
|
queryFn: () =>
|
|
getAllAmenities({ page: pageAmenities, page_size: pageSizeAmenities }),
|
|
select: (res) => res.data.data,
|
|
});
|
|
|
|
const pageMeal = parseInt(searchParams.get("pageMeal") || "1", 10);
|
|
const pageSizeMeal = parseInt(searchParams.get("pageSizeMeal") || "10", 10);
|
|
|
|
const {
|
|
data: mealData,
|
|
isLoading: mealLoad,
|
|
isError: mealError,
|
|
refetch: mealRef,
|
|
} = useQuery({
|
|
queryKey: ["all_meal", pageMeal, pageSizeMeal],
|
|
queryFn: () => hotelMealList({ page: pageMeal, page_size: pageSizeMeal }),
|
|
select: (res) => res.data.data,
|
|
});
|
|
|
|
const handleTabChange = (value: string) => {
|
|
setActiveTab(value);
|
|
navigate({
|
|
pathname: window.location.pathname,
|
|
search: "",
|
|
});
|
|
};
|
|
|
|
return (
|
|
<div className="min-h-screen bg-gray-900 p-6 w-full text-white">
|
|
<div className="max-w-[90%] mx-auto space-y-6">
|
|
<Tabs
|
|
value={activeTab}
|
|
onValueChange={handleTabChange}
|
|
className="w-full"
|
|
>
|
|
<TabsList className="w-full">
|
|
<TabsTrigger value="badge">{t("Belgilar (Badge)")}</TabsTrigger>
|
|
<TabsTrigger value="meal_plan">
|
|
{t("Ovqatlanish turlari")}
|
|
</TabsTrigger>
|
|
<TabsTrigger value="tarif">{t("Tariflar")}</TabsTrigger>
|
|
<TabsTrigger value="transport">{t("Transport")}</TabsTrigger>
|
|
<TabsTrigger value="meal">{t("Qulayliklar")}</TabsTrigger>
|
|
<TabsTrigger value="hotel_type">{t("Otel turlari")}</TabsTrigger>
|
|
<TabsTrigger value="hotel_features">
|
|
{t("Otel sharoitlari")}
|
|
</TabsTrigger>
|
|
<TabsTrigger value="country">{t("Davlatlar")}</TabsTrigger>
|
|
</TabsList>
|
|
|
|
<TabsContent value="badge" className="space-y-4">
|
|
{isLoading ? (
|
|
<LoadingDisplay />
|
|
) : isError ? (
|
|
<ErrorDisplay
|
|
message={t("Belgilarni yuklashda xatolik yuz berdi.")}
|
|
onRetry={refetch}
|
|
/>
|
|
) : (
|
|
<BadgeTable data={data} page={page} pageSize={pageSize} />
|
|
)}
|
|
</TabsContent>
|
|
|
|
<TabsContent value="tarif" className="space-y-4">
|
|
{tarifLoad ? (
|
|
<LoadingDisplay />
|
|
) : tarifError ? (
|
|
<ErrorDisplay
|
|
message={t("Tariflarni yuklashda xatolik yuz berdi.")}
|
|
onRetry={tarifRef}
|
|
/>
|
|
) : (
|
|
<TarifTable
|
|
data={tarifData}
|
|
page={pageTarif}
|
|
pageSize={pageSizeTarif}
|
|
/>
|
|
)}
|
|
</TabsContent>
|
|
|
|
<TabsContent value="transport" className="space-y-4">
|
|
{transportLoad ? (
|
|
<LoadingDisplay />
|
|
) : transportError ? (
|
|
<ErrorDisplay
|
|
message={t("Transportlarni yuklashda xatolik yuz berdi.")}
|
|
onRetry={transportRef}
|
|
/>
|
|
) : (
|
|
<TransportTable
|
|
data={transportData}
|
|
page={pageTransport}
|
|
pageSize={pageSizeTransport}
|
|
/>
|
|
)}
|
|
</TabsContent>
|
|
|
|
<TabsContent value="meal" className="space-y-4">
|
|
{amenitiesLoad ? (
|
|
<LoadingDisplay />
|
|
) : amenitiesError ? (
|
|
<ErrorDisplay
|
|
message={t("Qulayliklarni yuklashda xatolik yuz berdi.")}
|
|
onRetry={amenitiesRef}
|
|
/>
|
|
) : (
|
|
<Amenities
|
|
data={amenitiesData}
|
|
page={pageAmenities}
|
|
pageSize={pageSizeAmenities}
|
|
/>
|
|
)}
|
|
</TabsContent>
|
|
|
|
<TabsContent value="hotel_type" className="space-y-4">
|
|
{typeLoad ? (
|
|
<LoadingDisplay />
|
|
) : typeError ? (
|
|
<ErrorDisplay
|
|
message={t("Otel turlarini yuklashda xatolik yuz berdi.")}
|
|
onRetry={typeRef}
|
|
/>
|
|
) : (
|
|
<HotelType
|
|
data={typeData}
|
|
page={pageType}
|
|
pageSize={pageSizeType}
|
|
/>
|
|
)}
|
|
</TabsContent>
|
|
|
|
<TabsContent value="meal_plan" className="space-y-4">
|
|
{mealLoad ? (
|
|
<LoadingDisplay />
|
|
) : mealError ? (
|
|
<ErrorDisplay
|
|
message={t("Otel turlarini yuklashda xatolik yuz berdi.")}
|
|
onRetry={mealRef}
|
|
/>
|
|
) : (
|
|
<MealTable
|
|
data={mealData}
|
|
page={pageMeal}
|
|
pageSize={pageSizeMeal}
|
|
/>
|
|
)}
|
|
</TabsContent>
|
|
|
|
<TabsContent value="hotel_features" className="space-y-4">
|
|
{featureLoad ? (
|
|
<LoadingDisplay />
|
|
) : featureError ? (
|
|
<ErrorDisplay
|
|
message={t("Otel sharoitlarini yuklashda xatolik yuz berdi.")}
|
|
onRetry={featureRef}
|
|
/>
|
|
) : (
|
|
<FeaturesTable
|
|
data={featureData}
|
|
page={pageFeature}
|
|
pageSize={pageSizeFeature}
|
|
setActiveTab={setActiveTab}
|
|
setFeatureId={setFeatureId}
|
|
/>
|
|
)}
|
|
</TabsContent>
|
|
|
|
<TabsContent value="feature_type" className="space-y-4">
|
|
{featureTypeLoad ? (
|
|
<LoadingDisplay />
|
|
) : featureTypeError ? (
|
|
<ErrorDisplay
|
|
message={t("Sharoit turlarini yuklashda xatolik yuz berdi.")}
|
|
onRetry={featureTypeRef}
|
|
/>
|
|
) : (
|
|
<FeaturesTableType
|
|
data={featureTypeData}
|
|
page={pageFeature}
|
|
featureId={featureId}
|
|
pageSize={pageSizeFeature}
|
|
/>
|
|
)}
|
|
</TabsContent>
|
|
|
|
<TabsContent value="country" className="space-y-4">
|
|
{countryLoad ? (
|
|
<LoadingDisplay />
|
|
) : countryError ? (
|
|
<ErrorDisplay
|
|
message={t("Sharoit turlarini yuklashda xatolik yuz berdi.")}
|
|
onRetry={countryRef}
|
|
/>
|
|
) : (
|
|
<CountryTable
|
|
data={countryData}
|
|
page={pageCountry}
|
|
setActiveTab={setActiveTab}
|
|
setFeatureId={setCountryId}
|
|
pageSize={pageSizeCountry}
|
|
/>
|
|
)}
|
|
</TabsContent>
|
|
|
|
<TabsContent value="region" className="space-y-4">
|
|
{regionLoad ? (
|
|
<LoadingDisplay />
|
|
) : regionError ? (
|
|
<ErrorDisplay
|
|
message={t("Sharoit turlarini yuklashda xatolik yuz berdi.")}
|
|
onRetry={regionRef}
|
|
/>
|
|
) : (
|
|
<RegionTable
|
|
data={regionData}
|
|
page={pageRegion}
|
|
featureId={countryId}
|
|
pageSize={pageSizeRegion}
|
|
/>
|
|
)}
|
|
</TabsContent>
|
|
</Tabs>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default ToursSetting;
|