+ Mahsulot topilmadi +
++ Siz qidirayotgan mahsulot mavjud emas yoki o'chirilgan +
+ + Mahsulotlarga qaytish + +| - Feature - | -
|---|
| - {feature} - | -
+ Xususiyatlar +
+| + Xususiyat + | +
|---|
|
+
+ •
+ {feature}
+
+ |
+
+
{title}
{/* Article ID */}
-
-
- Artikul:
- {name}
-
+
+ Artikul:
+ {articular}
{/* Status Badge */}
-
-
- {statusText}
+
+
+ {status}
- {/* description */}
-
-
+ {/* Description */}
+
+
{description}
{/* Price Section */}
-
-
- 17.00$
-
-
- {/* Action Buttons */}
-
- {/* */}
-
- {/* */}
+
+ {/* Price */}
+
+ Narx:
+
+ ${price}
+
- {/* Social Share Icons */}
-
-
+ {/* Action Button */}
+
+
+ {/* Social Share */}
+
+
+
+ Ulashish:
+
+
{socialLinks.map((social) => (
@@ -122,4 +112,4 @@ export function RightSide({
);
-}
+}
\ No newline at end of file
diff --git a/components/pages/products/slug/slider.tsx b/components/pages/products/slug/slider.tsx
index 4cfb19b..349621c 100644
--- a/components/pages/products/slug/slider.tsx
+++ b/components/pages/products/slug/slider.tsx
@@ -1,60 +1,133 @@
"use client";
import { Swiper, SwiperSlide } from "swiper/react";
-import { Navigation } from "swiper/modules";
+import { Navigation, Pagination, Thumbs } from "swiper/modules";
+import { useState } from "react";
+import type { Swiper as SwiperType } from "swiper";
import "swiper/css";
import "swiper/css/navigation";
-import { DATA } from "@/lib/demoData";
+import "swiper/css/pagination";
+import "swiper/css/thumbs";
+import Image from "next/image";
-// The custom CSS selectors for navigation
const navigationPrevEl = ".custom-swiper-prev";
const navigationNextEl = ".custom-swiper-next";
export function SliderComp({ imgs }: { imgs: string[] }) {
+ const [thumbsSwiper, setThumbsSwiper] = useState(null);
+
+ // Agar rasm bo'lmasa
+ if (!imgs || imgs.length === 0) {
+ return (
+
+
+
+ Rasm mavjud emas
+
+
+ );
+ }
+
return (
-
-
+
+ {/* Main Slider */}
+
1}
+ className="w-[90%] h-96 md:h-96 rounded-lg overflow-hidden shadow-xl"
>
{imgs.map((image, index) => (
-
+
+
+
))}
- {/* Custom buttons */}
-
-
+
+ {/* Navigation Buttons */}
+ {imgs.length > 1 && (
+ <>
+
+
+ >
+ )}
+
+ {/* Thumbnail Slider */}
+ {imgs.length > 1 && (
+
+ {imgs.map((image, index) => (
+
+
+
+
+
+ ))}
+
+ )}
);
-}
+}
\ No newline at end of file
diff --git a/components/priceContact.tsx b/components/priceContact.tsx
index 56906b9..cbd2f76 100644
--- a/components/priceContact.tsx
+++ b/components/priceContact.tsx
@@ -1,10 +1,19 @@
"use client";
-
import { useTranslations } from "next-intl";
import Image from "next/image";
import { useState, useEffect } from "react";
import { X } from "lucide-react";
import { usePriceModalStore } from "@/store/useProceModalStore";
+import { useMutation } from "@tanstack/react-query";
+import httpClient from "@/request/api";
+import { endPoints } from "@/request/links";
+import { toast } from "react-toastify";
+
+interface FormType {
+ name: string;
+ product: number;
+ phone: number; // ✅ String bo'lishi kerak
+}
export function PriceModal() {
const t = useTranslations("priceModal");
@@ -13,31 +22,41 @@ export function PriceModal() {
const [formData, setFormData] = useState({
name: "",
phone: "+998 ",
- captcha: "",
});
const [errors, setErrors] = useState({
name: "",
phone: "",
- captcha: "",
});
- const [captchaCode, setCaptchaCode] = useState("");
- const [isSubmitting, setIsSubmitting] = useState(false);
-
- // Generate random captcha
- useEffect(() => {
- if (isOpen) {
- const code = Math.random().toString(36).substring(2, 8).toUpperCase();
- setCaptchaCode(code);
- }
- }, [isOpen]);
+ const formRequest = useMutation({
+ mutationFn: (data: FormType) =>
+ httpClient.post(endPoints.post.productContact, data),
+ onSuccess: () => {
+ setFormData({
+ name: "",
+ phone: "+998 ",
+ });
+ toast.success(t("success") || "Muvaffaqiyatli yuborildi!");
+ closeModal();
+ },
+ onError: (error) => {
+ console.error("Error:", error);
+ toast.error(t("error") || "Xatolik yuz berdi");
+ },
+ });
// Reset form when modal closes
useEffect(() => {
if (!isOpen) {
- setFormData({ name: "", phone: "+998 ", captcha: "" });
- setErrors({ name: "", phone: "", captcha: "" });
+ setFormData({
+ name: "",
+ phone: "+998 ",
+ });
+ setErrors({
+ name: "",
+ phone: "",
+ });
}
}, [isOpen]);
@@ -58,15 +77,14 @@ export function PriceModal() {
if (!numbers.startsWith("998")) {
return "+998 ";
}
-
+
let formatted = "+998 ";
const rest = numbers.slice(3);
-
if (rest.length > 0) formatted += rest.slice(0, 2);
if (rest.length > 2) formatted += " " + rest.slice(2, 5);
if (rest.length > 5) formatted += " " + rest.slice(5, 7);
if (rest.length > 7) formatted += " " + rest.slice(7, 9);
-
+
return formatted;
};
@@ -90,51 +108,45 @@ export function PriceModal() {
const newErrors = {
name: "",
phone: "",
- captcha: "",
};
+ // Name validation
if (!formData.name.trim()) {
- newErrors.name = t("validation.nameRequired");
+ newErrors.name = t("validation.nameRequired") || "Ism kiritilishi shart";
}
+ // Phone validation
const phoneNumbers = formData.phone.replace(/\D/g, "");
if (phoneNumbers.length !== 12) {
- newErrors.phone = t("validation.phoneRequired");
+ newErrors.phone =
+ t("validation.phoneRequired") || "To'liq telefon raqam kiriting";
} else if (!phoneNumbers.startsWith("998")) {
- newErrors.phone = t("validation.phoneInvalid");
- }
-
- if (!formData.captcha.trim()) {
- newErrors.captcha = t("validation.captchaRequired");
- } else if (formData.captcha.toUpperCase() !== captchaCode) {
- newErrors.captcha = t("validation.captchaRequired");
+ newErrors.phone =
+ t("validation.phoneInvalid") || "Noto'g'ri telefon raqam";
}
setErrors(newErrors);
- return !newErrors.name && !newErrors.phone && !newErrors.captcha;
+ return !newErrors.name && !newErrors.phone;
};
- const handleSubmit = async (e: React.FormEvent) => {
+ const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!validateForm()) {
return;
}
- setIsSubmitting(true);
+ // Telefon raqamni tozalash (faqat raqamlar)
+ const cleanPhone = formData.phone.replace(/\D/g, "");
- try {
- // API call logikangiz
- await new Promise((resolve) => setTimeout(resolve, 1500));
+ const sendedData: FormType = {
+ name: formData.name,
+ phone: Number(cleanPhone), // ✅ String sifatida yuborish
+ product: product?.id || 0,
+ };
- // Success
- alert(t("success"));
- closeModal();
- } catch (error) {
- alert(t("error"));
- } finally {
- setIsSubmitting(false);
- }
+ console.log("Sended data:", sendedData);
+ formRequest.mutate(sendedData);
};
if (!isOpen || !product) return null;
@@ -143,49 +155,58 @@ export function PriceModal() {
{/* Backdrop */}
{/* Modal */}
-
+
{/* Close button */}
{/* Content */}
-
- {t("title")}
+
+
+ {t("title") || "Narx so'rash"}
+
{/* Product Info */}
-
-
+
+
-
- {product.name}
-
- {t("product.inStock")}
+
+
+ {product.name}
+
+
+ {product.inStock
+ ? t("product.inStock") || "Sotuvda mavjud"
+ : t("product.outOfStock") || "Sotuvda yo'q"}
{/* Form */}
-
- Artikul: - {name} -
++ {/* Description */} +
{description}
- 17.00$ -
- - {/* Action Buttons */} -Narx:
++ ${price} +
Rasm mavjud emas
+