connected to backend
This commit is contained in:
@@ -3,45 +3,85 @@
|
||||
import { useCarDetail } from "@/components/lib_components/carDetailProvider";
|
||||
import Text from "@/components/lib_components/text";
|
||||
import Image from "next/image";
|
||||
import React, { useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import CarRentalModal from "@/components/lib_components/carRentalModal";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useCarType } from "@/store/carType";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { logoImg } from "@/assets";
|
||||
|
||||
const baseUrl = "https://api.spes-texnika.uz/api/v1/products/";
|
||||
|
||||
export default function CarDetailPage() {
|
||||
const { detail } = useCarDetail();
|
||||
const [modalOpen, setModalOpen] = useState<boolean>(false);
|
||||
const { t } = useTranslation();
|
||||
|
||||
if (!detail) {
|
||||
return (
|
||||
<div className="my-20 text-center text-gray-500">
|
||||
<Text txt="Mahsulot topilmadi yoki hali tanlanmagan." />
|
||||
</div>
|
||||
);
|
||||
// tools of request
|
||||
const initialCar = useCarType((state) => state.initialCar);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const pathname = usePathname();
|
||||
const lang = pathname.split("/")[1];
|
||||
const [cars, setCars] = useState<any[]>([]);
|
||||
|
||||
console.log("car type id: ", initialCar.id);
|
||||
console.log("request URL: ", `${baseUrl}${initialCar.id}/`);
|
||||
|
||||
useEffect(() => {
|
||||
// Agar ID bo'lmasa, fetchni ishga tushirma
|
||||
if (!initialCar.id) {
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const fetchProducts = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
const response = await fetch(`${baseUrl}${initialCar.id}/`, {
|
||||
headers: {
|
||||
"Accept-Language": lang,
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Server xatosi");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
console.log("backend full response: ", result);
|
||||
console.log("backend Data: ", result?.data);
|
||||
|
||||
// Data array ekanligini tekshirish
|
||||
if (result?.data) {
|
||||
if (Array.isArray(result.data)) {
|
||||
setCars(result.data);
|
||||
} else {
|
||||
// Agar object bo'lsa, uni array ichiga o'rab qo'yamiz
|
||||
setCars([result.data]);
|
||||
}
|
||||
} else {
|
||||
setCars([]);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("Xatolik: ", error);
|
||||
setError(error instanceof Error ? error.message : "Noma'lum xatolik");
|
||||
setCars([]);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchProducts();
|
||||
}, [lang]); // initialCar.id ham dependency ga qo'shildi
|
||||
|
||||
const firstData = cars ? cars[0] : undefined;
|
||||
|
||||
if (!firstData) {
|
||||
return <>Maluot topilmadi</>;
|
||||
}
|
||||
|
||||
const {t} = useTranslation();
|
||||
|
||||
const techSpecs: Record<string, string | number | undefined> = {
|
||||
[t("weight_kg")]: detail.weight_kg && `${detail.weight_kg.toLocaleString("uz-UZ")} kg`,
|
||||
[t("maxLength_m")]: detail.maxLength_m && `${detail.maxLength_m} m`,
|
||||
[t("maxHeight_m")]: detail.maxHeight_m && `${detail.maxHeight_m} m`,
|
||||
[t("capacity_tons")]: detail.capacity_tons && `${detail.capacity_tons} t`,
|
||||
[t("capacity_kg")]: detail.capacity_kg && `${detail.capacity_kg} kg`,
|
||||
[t("fuelType")]: detail.fuelType,
|
||||
[t("tankVolume_m3")]: detail.tankVolume_m3 && `${detail.tankVolume_m3} m³`,
|
||||
[t("maxSpeed_kmh")]: detail.maxSpeed_kmh && `${detail.maxSpeed_kmh} km/soat`,
|
||||
[t("intercooler")]: detail.intercooler,
|
||||
[t("enginePower_hp")]: detail.enginePower_hp,
|
||||
[t("transmission")]: detail.transmission,
|
||||
[t("bom")]: detail.bom && `${detail.bom} m`,
|
||||
[t("qazish")]: detail.qazish && `${detail.qazish} m`,
|
||||
[t("pichoq")]: detail.pichoq && `${detail.pichoq} m`,
|
||||
[t("zichlash")]: detail.zichlash && `${detail.zichlash} m`,
|
||||
[t("siqish")]: detail.siqish && `${detail.siqish} bar`,
|
||||
[t("havo")]: detail.havo && `${detail.havo} l`,
|
||||
[t("kompressor_sig")]: detail.kompressor_sig && `${detail.kompressor_sig} l`
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
dir="ltr"
|
||||
@@ -49,7 +89,7 @@ export default function CarDetailPage() {
|
||||
>
|
||||
{/* 1️⃣ Mashina nomi */}
|
||||
<div className="text-2xl font-bold w-full text-center text-secondary mb-10">
|
||||
<Text txt={detail.name} />
|
||||
<Text txt={""} />
|
||||
</div>
|
||||
|
||||
{/* 2️⃣ Rasmi + asosiy narx ma’lumotlari */}
|
||||
@@ -57,8 +97,8 @@ export default function CarDetailPage() {
|
||||
{/* Mashina rasmi */}
|
||||
<div className="max-w-[600px] w-full h-auto">
|
||||
<Image
|
||||
src={detail.image}
|
||||
alt={detail.name}
|
||||
src={firstData?.image ? firstData?.image : logoImg}
|
||||
alt={firstData?.name ? firstData?.name : "image"}
|
||||
width={600}
|
||||
height={200}
|
||||
className="rounded-lg object-cover border border-gray-200 w-full"
|
||||
@@ -70,24 +110,17 @@ export default function CarDetailPage() {
|
||||
<div className="text-lg font-semibold flex gap-2">
|
||||
<Text txt="hour-price" />
|
||||
<span className="font-medium flex gap-2 text-gray-500">
|
||||
{detail.price?.toLocaleString("uz-UZ")}
|
||||
{firstData.price?.toLocaleString("uz-UZ")}
|
||||
<Text txt="wallet" />
|
||||
</span>
|
||||
</div>
|
||||
<div className="text-lg font-semibold flex gap-2">
|
||||
<Text txt="min-time" />
|
||||
<span className="font-medium flex gap-2 text-gray-500">
|
||||
{detail.min_order_time}
|
||||
{firstData.minimal_order}
|
||||
<Text txt="time" />
|
||||
</span>
|
||||
</div>
|
||||
<div className="text-lg font-semibold flex gap-2">
|
||||
<Text txt="day-price" />
|
||||
<span className="font-medium flex gap-2 text-gray-500">
|
||||
{detail.price && (detail.price * 8).toLocaleString("uz-UZ")}
|
||||
<Text txt="wallet" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Izoh */}
|
||||
<div className="space-y-2 text-gray-500 text-lg">
|
||||
@@ -110,25 +143,25 @@ export default function CarDetailPage() {
|
||||
|
||||
{/* 3️⃣ Texnik xususiyatlar (faqat mavjudlari) */}
|
||||
<div className="w-full border-t border-gray-300 pt-6">
|
||||
<h2 className="text-xl font-semibold mb-4 text-secondary">Texnik xususiyatlari</h2>
|
||||
<h2 className="text-xl font-semibold mb-4 text-secondary">
|
||||
Texnik xususiyatlari
|
||||
</h2>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 text-gray-700">
|
||||
{Object.entries(techSpecs)
|
||||
.filter(([_, value]) => value !== undefined)
|
||||
.map(([key, value]) => (
|
||||
<div
|
||||
key={key}
|
||||
className="p-3 rounded-md bg-gray-50 border border-gray-200 hover:bg-gray-100 transition"
|
||||
>
|
||||
<p className="font-medium">{key}:</p>
|
||||
<p className="text-gray-600">{value}</p>
|
||||
</div>
|
||||
))}
|
||||
{firstData?.features.map((item: any) => (
|
||||
<div
|
||||
key={item.id}
|
||||
className="p-3 rounded-md bg-gray-50 border border-gray-200 hover:bg-gray-100 transition"
|
||||
>
|
||||
<p className="font-medium">{item?.name}:</p>
|
||||
<p className="text-gray-600">{item?.value}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 4️⃣ Ijara modal */}
|
||||
<CarRentalModal
|
||||
car={detail}
|
||||
car={firstData}
|
||||
isOpen={modalOpen}
|
||||
onClose={() => setModalOpen(false)}
|
||||
/>
|
||||
|
||||
@@ -1,194 +1,100 @@
|
||||
"use client";
|
||||
|
||||
import InnerProductcard from "@/components/cards/innerProductcard";
|
||||
import { EmptyState } from "@/components/emptyState";
|
||||
import Text from "@/components/lib_components/text";
|
||||
import Title from "@/components/lib_components/title";
|
||||
import {
|
||||
asfalt,
|
||||
assenizator,
|
||||
avtogreyderlar,
|
||||
avtokran,
|
||||
avtolift,
|
||||
avtovishka,
|
||||
betonNasoslar,
|
||||
buldozerlar,
|
||||
cement_trucks,
|
||||
dumb_trucks,
|
||||
eks_yuklagichlar,
|
||||
evakuatorDemo,
|
||||
forkliftlar,
|
||||
gildirakli_eks,
|
||||
katkalar,
|
||||
manipulyator,
|
||||
mini_eks,
|
||||
mini_loaders,
|
||||
minora,
|
||||
old_yuklagichlar,
|
||||
paletli_eks,
|
||||
shalandaTraller,
|
||||
teleskop_yuklagichlar,
|
||||
trailers,
|
||||
vodovoz,
|
||||
} from "@/data";
|
||||
import { useParams } from "next/navigation";
|
||||
import { LoadingSkeleton } from "@/components/loadingProduct";
|
||||
import { useCarType } from "@/store/carType";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
const baseUrl = "https://api.spes-texnika.uz/api/v1/subcategory/";
|
||||
|
||||
export default function CartType() {
|
||||
const router = useParams();
|
||||
const carType = router.carType;
|
||||
const initialCar = useCarType((state) => state.initialCar);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const pathname = usePathname();
|
||||
const lang = pathname.split("/")[1];
|
||||
const [cars, setCars] = useState<any[]>([]);
|
||||
|
||||
console.log("car type id: ", initialCar.id);
|
||||
console.log("request URL: ", `${baseUrl}${initialCar.id}/`);
|
||||
|
||||
useEffect(() => {
|
||||
// Agar ID bo'lmasa, fetchni ishga tushirma
|
||||
if (!initialCar.id) {
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const fetchProducts = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
const response = await fetch(`${baseUrl}${initialCar.id}/`, {
|
||||
headers: {
|
||||
"Accept-Language": lang,
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Server xatosi");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
console.log("backend full response: ", result);
|
||||
console.log("backend Data: ", result?.data);
|
||||
|
||||
// Data array ekanligini tekshirish
|
||||
if (result?.data) {
|
||||
if (Array.isArray(result.data)) {
|
||||
setCars(result.data);
|
||||
} else {
|
||||
// Agar object bo'lsa, uni array ichiga o'rab qo'yamiz
|
||||
setCars([result.data]);
|
||||
}
|
||||
} else {
|
||||
setCars([]);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("Xatolik: ", error);
|
||||
setError(error instanceof Error ? error.message : "Noma'lum xatolik");
|
||||
setCars([]);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchProducts();
|
||||
}, [lang]); // initialCar.id ham dependency ga qo'shildi
|
||||
|
||||
return (
|
||||
<div dir="ltr" className="my-20">
|
||||
<Title text="tex-rent" />
|
||||
|
||||
{/* Error message */}
|
||||
{error && (
|
||||
<div className="mb-4 p-4 bg-red-50 border border-red-200 rounded-lg">
|
||||
<p className="text-red-600 text-center">
|
||||
<Text txt="downloadError" />: {error}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* car type groups */}
|
||||
<div className="mt-10 grid lg:grid-cols-3 sm:grid-cols-2 grid-cols-1 gap-5 max-w-[1200px] w-full mx-auto">
|
||||
{/* Avtosementavoz */}
|
||||
{carType === "cement-truck" &&
|
||||
cement_trucks.map((item) => {
|
||||
return <InnerProductcard data={item} key={item.id} />;
|
||||
})}
|
||||
|
||||
{/* Samasvallar */}
|
||||
{carType === "dumb-truck" &&
|
||||
dumb_trucks.map((item) => {
|
||||
return <InnerProductcard data={item} key={item.id} />;
|
||||
})}
|
||||
|
||||
{/* Traylerlar */}
|
||||
{carType === "trailers" &&
|
||||
trailers.map((item) => {
|
||||
return <InnerProductcard data={item} key={item.id} />;
|
||||
})}
|
||||
|
||||
{/* Avtoliftlar */}
|
||||
{carType === "Avtolift" &&
|
||||
avtolift.map((item) => {
|
||||
return <InnerProductcard data={item} key={item.id} />;
|
||||
})}
|
||||
|
||||
{/* Avtovishka */}
|
||||
{carType === "Avtovishka" &&
|
||||
avtovishka.map((item) => {
|
||||
return <InnerProductcard data={item} key={item.id} />;
|
||||
})}
|
||||
|
||||
{/* Avtokran */}
|
||||
{carType === "avtocranes" &&
|
||||
avtokran.map((item) => {
|
||||
return <InnerProductcard data={item} key={item.id} />;
|
||||
})}
|
||||
|
||||
{/* Minora kranlar */}
|
||||
{carType === "tower-cranes" &&
|
||||
minora.map((item) => {
|
||||
return <InnerProductcard data={item} key={item.id} />;
|
||||
})}
|
||||
|
||||
{/* Minora kranlar */}
|
||||
{carType === "mini-loaders" &&
|
||||
mini_loaders.map((item) => {
|
||||
return <InnerProductcard data={item} key={item.id} />;
|
||||
})}
|
||||
|
||||
{/* old yuklagichlar */}
|
||||
{carType === "front-loaders" &&
|
||||
old_yuklagichlar.map((item) => {
|
||||
return <InnerProductcard data={item} key={item.id} />;
|
||||
})}
|
||||
|
||||
{/* Teleskopik yuklagichlar */}
|
||||
{carType === "tele-loaders" &&
|
||||
teleskop_yuklagichlar.map((item) => {
|
||||
return <InnerProductcard data={item} key={item.id} />;
|
||||
})}
|
||||
|
||||
{/* forkliftlar */}
|
||||
{carType === "forklift-trucks" &&
|
||||
forkliftlar.map((item) => {
|
||||
return <InnerProductcard data={item} key={item.id} />;
|
||||
})}
|
||||
|
||||
{/* Paletli ekskavatorlar */}
|
||||
{carType === "crawler-excavators" &&
|
||||
paletli_eks.map((item) => {
|
||||
return <InnerProductcard data={item} key={item.id} />;
|
||||
})}
|
||||
|
||||
{/* G'ildirakli ekskavatorlar */}
|
||||
{carType === "wheel-excavators" &&
|
||||
gildirakli_eks.map((item) => {
|
||||
return <InnerProductcard data={item} key={item.id} />;
|
||||
})}
|
||||
|
||||
{/* Mini-ekskavatorlar */}
|
||||
{carType === "mini-excavators" &&
|
||||
mini_eks.map((item) => {
|
||||
return <InnerProductcard data={item} key={item.id} />;
|
||||
})}
|
||||
|
||||
{/* ekskavator yuklagichlar */}
|
||||
{carType === "excavator-loaders" &&
|
||||
eks_yuklagichlar.map((item) => {
|
||||
return <InnerProductcard data={item} key={item.id} />;
|
||||
})}
|
||||
|
||||
{/* avtogreyderlar */}
|
||||
{carType === "avtograders" &&
|
||||
avtogreyderlar.map((item) => {
|
||||
return <InnerProductcard data={item} key={item.id} />;
|
||||
})}
|
||||
|
||||
{/* Buldozerlar */}
|
||||
{carType === "buldozers" &&
|
||||
buldozerlar.map((item) => {
|
||||
return <InnerProductcard data={item} key={item.id} />;
|
||||
})}
|
||||
|
||||
{/* Katkalar */}
|
||||
{carType === "katkas" &&
|
||||
katkalar.map((item) => {
|
||||
return <InnerProductcard data={item} key={item.id} />;
|
||||
})}
|
||||
|
||||
{/* Evakuatorlar */}
|
||||
{carType === "evakuator" &&
|
||||
evakuatorDemo.map((item) => {
|
||||
return <InnerProductcard data={item} key={item.id} />;
|
||||
})}
|
||||
|
||||
{/* shalanda */}
|
||||
{carType === "shalanda_traller" &&
|
||||
shalandaTraller.map((item) => {
|
||||
return <InnerProductcard data={item} key={item.id} />;
|
||||
})}
|
||||
|
||||
{/* asfalt yotqizuvchi */}
|
||||
{carType === "asfalt_frez" &&
|
||||
asfalt.map((item) => {
|
||||
return <InnerProductcard data={item} key={item.id} />;
|
||||
})}
|
||||
|
||||
{/* asfalt ko'chiruvchi */}
|
||||
{carType === "beton_nasos" &&
|
||||
betonNasoslar.map((item) => {
|
||||
return <InnerProductcard data={item} key={item.id} />;
|
||||
})}
|
||||
|
||||
{/* manipulyator */}
|
||||
{carType === "manipulyator" &&
|
||||
manipulyator.map((item) => {
|
||||
return <InnerProductcard data={item} key={item.id} />;
|
||||
})}
|
||||
|
||||
{/* vodovoz */}
|
||||
{carType === "vodovoz" &&
|
||||
vodovoz.map((item) => {
|
||||
return <InnerProductcard data={item} key={item.id} />;
|
||||
})}
|
||||
|
||||
{/* assertizator */}
|
||||
{carType === "assenizator" &&
|
||||
assenizator.map((item) => {
|
||||
return <InnerProductcard data={item} key={item.id} />;
|
||||
})}
|
||||
<div className="mt-10 grid lg:grid-cols-3 sm:grid-cols-2 grid-cols-1 gap-5 max-w-[1200px] w-full mx-auto px-4">
|
||||
{loading ? (
|
||||
<LoadingSkeleton />
|
||||
) : cars.length > 0 ? (
|
||||
// MUHIM: Array ustidan map qilish kerak!
|
||||
cars.map((car, index) => (
|
||||
<InnerProductcard key={car.id || index} data={car} />
|
||||
))
|
||||
) : (
|
||||
<EmptyState />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Products from "@/components/pageParts/products";
|
||||
import Products from "@/components/pageParts/products/products";
|
||||
import Texnika from "@/components/pageParts/texnika";
|
||||
import Offer from "@/components/pageParts/offer";
|
||||
import Faq from "@/components/pageParts/faq";
|
||||
@@ -27,4 +27,3 @@ export default function Home() {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user