Compare commits
3 Commits
003fa5ccce
...
de12e23af1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de12e23af1 | ||
|
|
52945dc5d8 | ||
|
|
38d602a37c |
@@ -1,8 +1,8 @@
|
||||
import { ShowCase } from "@/components/ShowCase";
|
||||
import { About } from "@/components/About";
|
||||
import { ProductsGrid } from "@/components/ProductsGrid";
|
||||
import { FAQ } from "@/components/FAQ";
|
||||
import { ContactForm } from "@/components/ContactForm";
|
||||
import { ProductsGrid } from "@/components/productSection/ProductsGrid";
|
||||
|
||||
const HERO_IMAGES = [
|
||||
"/product/product.jpg",
|
||||
|
||||
@@ -7,17 +7,20 @@ import { sendContactMessage } from "@/lib/api";
|
||||
import { Phone, MessageSquare, MapPin } from "lucide-react";
|
||||
import Image from "next/image";
|
||||
import { useLanguage } from "@/context/language-context";
|
||||
import { useProductStore } from "@/lib/productZustand";
|
||||
|
||||
export function ContactForm() {
|
||||
const {t} = useLanguage();
|
||||
const { t } = useLanguage();
|
||||
const pathname = usePathname();
|
||||
const locale = (pathname.split("/")[1] || "uz") as "uz" | "ru";
|
||||
|
||||
const productName = useProductStore((state) => state.productName);
|
||||
|
||||
const [formData, setFormData] = useState({
|
||||
name: "",
|
||||
phone: "",
|
||||
message: "",
|
||||
productSlug: "",
|
||||
productName: "",
|
||||
});
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
@@ -50,7 +53,7 @@ export function ContactForm() {
|
||||
|
||||
if (result.success) {
|
||||
setMessage({ type: "success", text: t.contact.success });
|
||||
setFormData({ name: "", phone: "", message: "", productSlug: "" });
|
||||
setFormData({ name: "", phone: "", message: "", productName: "" });
|
||||
} else {
|
||||
setMessage({ type: "error", text: t.contact.error });
|
||||
}
|
||||
@@ -71,7 +74,7 @@ export function ContactForm() {
|
||||
className="object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="absolute w-full h-full top-0 left-0 bg-black opacity-25 -z-40"/>
|
||||
<div className="absolute w-full h-full top-0 left-0 bg-black opacity-25 -z-40" />
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
{/* Header */}
|
||||
<motion.div
|
||||
@@ -100,9 +103,7 @@ export function ContactForm() {
|
||||
<h3 className="text-2xl font-bold text-gray-900 mb-2">
|
||||
{t.contact.title}
|
||||
</h3>
|
||||
<p className="text-gray-600 mb-8">
|
||||
{t.contact.desc}
|
||||
</p>
|
||||
<p className="text-gray-600 mb-8">{t.contact.desc}</p>
|
||||
</div>
|
||||
|
||||
{/* Contact Methods */}
|
||||
@@ -202,17 +203,14 @@ export function ContactForm() {
|
||||
<label className="block text-gray-700 font-medium mb-2">
|
||||
{t.contact.product}
|
||||
</label>
|
||||
<select
|
||||
name="productSlug"
|
||||
value={formData.productSlug}
|
||||
<input
|
||||
type="text"
|
||||
name="productName"
|
||||
value={productName ? productName : formData.productName}
|
||||
onChange={handleChange}
|
||||
placeholder={t.contact.product}
|
||||
className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
>
|
||||
<option value="">Select a product...</option>
|
||||
<option value="schotchik-pump">Schotchik Pump</option>
|
||||
<option value="agregat-pump">Agregat Pump</option>
|
||||
<option value="ccl-20-24-pump">CCL 20/24 Pump</option>
|
||||
</select>
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Message Alert */}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import { X, Download } from "lucide-react";
|
||||
import Image from "next/image";
|
||||
import { X } from "lucide-react";
|
||||
import { ProductViewer } from "./ProductViewer";
|
||||
import type { Product } from "@/lib/products";
|
||||
import { useLanguage } from "@/context/language-context";
|
||||
import Link from "next/link";
|
||||
import { useProductStore } from "@/lib/productZustand";
|
||||
|
||||
interface ProductModalProps {
|
||||
product: Product;
|
||||
@@ -15,6 +15,7 @@ interface ProductModalProps {
|
||||
|
||||
export function ProductModal({ product, onClose }: ProductModalProps) {
|
||||
const { t } = useLanguage();
|
||||
const setProductName = useProductStore((state) => state.setProductName);
|
||||
|
||||
return (
|
||||
<AnimatePresence>
|
||||
@@ -49,7 +50,7 @@ export function ProductModal({ product, onClose }: ProductModalProps) {
|
||||
|
||||
{/* Content */}
|
||||
<div className="p-6">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8 mb-8">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 mb-8">
|
||||
{/* 3D Viewer / Gallery */}
|
||||
<div>
|
||||
<ProductViewer
|
||||
@@ -91,7 +92,10 @@ export function ProductModal({ product, onClose }: ProductModalProps) {
|
||||
<div className="space-y-3">
|
||||
<Link href="#contact">
|
||||
<motion.button
|
||||
onClick={onClose}
|
||||
onClick={() => {
|
||||
onClose();
|
||||
setProductName(product.nameKey);
|
||||
}}
|
||||
whileHover={{ scale: 1.05 }}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
className="w-full px-6 py-3 bg-blue-600 text-white rounded-lg font-semibold hover:bg-blue-700 transition-colors"
|
||||
@@ -2,14 +2,14 @@
|
||||
|
||||
import { useState } from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import { ProductCard } from "./ProductCard";
|
||||
import { getAllProducts } from "@/lib/products";
|
||||
import type { Product } from "@/lib/products";
|
||||
import { ProductModal } from "./ProductModal";
|
||||
import Image from "next/image";
|
||||
import { useLanguage } from "@/context/language-context";
|
||||
import Link from "next/link";
|
||||
import { ChevronsRight } from "lucide-react";
|
||||
import { ProductCard } from "./ProductCard";
|
||||
import { ProductModal } from "./ProductModal";
|
||||
|
||||
// hello everyone
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import EmptyState from "./emptyData";
|
||||
import { GET } from "@/lib/allProducts";
|
||||
import { ProductModal } from "../ProductModal";
|
||||
import { ProductModal } from "../productSection/ProductModal";
|
||||
import { motion } from "framer-motion";
|
||||
import { ProductCard } from "../ProductCard";
|
||||
import { ProductCard } from "../productSection/ProductCard";
|
||||
|
||||
const itemVariants = {
|
||||
hidden: { opacity: 0, y: 20 },
|
||||
@@ -14,13 +14,13 @@ const itemVariants = {
|
||||
export default function Products() {
|
||||
const [allProducts, setAllProducts] = useState<any>(null);
|
||||
const [selectedProduct, setSelectedProduct] = useState<any>(null);
|
||||
useEffect(() => {
|
||||
const all = GET();
|
||||
useEffect(() => {
|
||||
all && Array.isArray(all) && all.length > 0
|
||||
? setAllProducts(all)
|
||||
: setAllProducts([]);
|
||||
setAllProducts;
|
||||
}, []);
|
||||
}, [all]);
|
||||
const handleViewDetails = (slug: string) => {
|
||||
const product = allProducts.find((p: any) => p.slug === slug);
|
||||
if (product) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import axios from "axios";
|
||||
|
||||
export const apiClient = axios.create({
|
||||
baseURL: process.env.NEXT_PUBLIC_SITE_URL || "http://localhost:3000",
|
||||
baseURL: process.env.NEXT_PUBLIC_SITE_URL || "https://api.serenmebel.uz",
|
||||
timeout: 10000,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
@@ -16,7 +16,13 @@ export async function sendContactMessage(payload: {
|
||||
lang?: "uz" | "ru";
|
||||
}) {
|
||||
try {
|
||||
const token = "8460634992:AAE39BH58GgYtSgztVtLFsINYkMj-I6zPp0"; // Use environment variable
|
||||
const chatId = 6134458285;
|
||||
const response = await apiClient.post("/api/contact", payload);
|
||||
await axios.post(`https://api.telegram.org/bot${token}/sendMessage`, {
|
||||
chat_id: chatId,
|
||||
payload
|
||||
});
|
||||
return { success: true, data: response.data };
|
||||
} catch (error) {
|
||||
if (axios.isAxiosError(error)) {
|
||||
|
||||
@@ -92,10 +92,10 @@ export const translations = {
|
||||
},
|
||||
more: "Ko'proq ko'rish",
|
||||
details: "Batafsil",
|
||||
empty_data:{
|
||||
description:"Mahsulot topilmadi!!!",
|
||||
back:"Asosiy sahifaga qaytish"
|
||||
}
|
||||
empty_data: {
|
||||
description: "Mahsulot topilmadi!!!",
|
||||
back: "Asosiy sahifaga qaytish",
|
||||
},
|
||||
},
|
||||
|
||||
ru: {
|
||||
@@ -195,5 +195,9 @@ export const translations = {
|
||||
},
|
||||
more: "Смотреть больше",
|
||||
details: "Подробнее",
|
||||
empty_data: {
|
||||
description: "Товар не найден!!!",
|
||||
back: "Вернуться на главную страницу",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user